Steps to get the projects ready:
Create a silverlight app
Create a class library project in the same solution for Unit tests.
Add NUnit.Framework Reference
Add reference to the silverlight app.
Then I got this error when I was trying to reference my silverlight application in a Unit Test assembly.
The type 'System.Windows.Controls.UserControl' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Windows, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'.
According to my installation, the file is in:
c:\Program Files\Microsoft SDKs\Silverlight\v2.0\Reference Assemblies\System.Windows.dll
Pretty standard really but the GAC didn’t have the assembly surprisingly.
I tried to run a ‘basic test’ to see if the constructor worked.
I got this error:
Could not load file or assembly 'System, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' or one of its dependencies. The system cannot find the file specified.
System.IO.FileNotFoundException: Could not load file or assembly 'System, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' or one of its dependencies. The system cannot find the file specified.
File name: 'System, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'
I tried to add Silverlights System assembly:
Located here: c:\Program Files\Microsoft SDKs\Silverlight\v2.0\Reference Assemblies\system.dll
I had to remove the regular .net 2.0 System first.
Then when I ran my test, I get this error…
TestCase 'SilverlightApplication1.UnitTests.PageTests.Constructor_Loads' failed: TestFixtureSetUp failed in PageTests
So now I’m kinda angry. I can’t add both system dlls because I get conflicts. I’m sure both use the same namespace too! L
Ok, but that doesn’t deter me.
I get out the nunit.framework.dll source code and I try replacing system.dll with the silverlight system.dll.
I get the same error message.
So… maybe I’m chasing my tail here. I remove the reference to the silverlight Page and just create a new class inside the silverlight app that doesn’t depend on anything.
Whew, now my constructor test worked!
So this means there’s some hidden dependency inside UserControl that’s causing me to fail construction. Hrm what could it be?
I put my test fixture back to inheriting from the Page like so:
[TestFixture]
public class PageTests : Page
{
[Test]
public void Constructor_Loads()
{
Assert.That(true);
}
}
Cool, now let’s see what protected virtuals there are to override because maybe one of them is a seam (see michael feather’s book on legacy code)
Wow, quite a few… I guess I’ll just add one at a time and leave them empty (so they don’t do anything)
So I tried each of these one at a time and got no where.
[TestFixture]
public class PageTests : Page
{
protected override System.Windows.Size ArrangeOverride(System.Windows.Size finalSize)
{
return new System.Windows.Size();
}
public override void OnApplyTemplate()
{
}
protected override System.Windows.Size MeasureOverride(System.Windows.Size availableSize)
{
return new System.Windows.Size();
}
protected override System.Windows.Automation.Peers.AutomationPeer OnCreateAutomationPeer()
{
//i couldn't find a subclass of automationpeer that i could construct, but when i ran the test i didn't get this exception
throw new NotImplementedException();
}
protected override void OnGotFocus(System.Windows.RoutedEventArgs e)
{
}
protected override void OnLostFocus(System.Windows.RoutedEventArgs e)
{
}
[Test]
public void Constructor_Loads()
{
Assert.That(true);
}
}
So man, what could it be? Maybe something in the default constructor. So let’s try this:
[TestFixture]
public class PageTests
{
[Test]
public void Constructor_Loads()
{
Page pg = new Page();
}
}
I should have done this from the beginning… because now I get a much more sensible error!
----> System.UnauthorizedAccessException : InvalidCrossThreadAccess
at System.Windows.DependencyObject..ctor(UInt32 nativeTypeIndex)
at System.Windows.Controls.UserControl..ctor()
C:\Users\James\Documents\Visual Studio 2008\Projects\SilverlightApplication1\SilverlightApplication1\Page.xaml.cs(17,0): at SilverlightApplication1.Page..ctor()
C:\Users\James\Documents\Visual Studio 2008\Projects\SilverlightApplication1\SilverlightApplication1.UnitTests\PageTests.cs(15,0): at SilverlightApplication1.UnitTests.PageTests.Constructor_Loads()
--UnauthorizedAccessException
at MS.Internal.XcpImports.CheckThread()
at System.Windows.DependencyObject..ctor(UInt32 nativeTypeIndex, IntPtr constructDO)
at System.Windows.DependencyObject..ctor()
at System.Windows.DependencyObject.ManagedReferencesToken..ctor()
at System.Windows.DependencyObject..cctor()
Cross thread access… strange. I don’t see anywhere in my code that I’m using multiple threads. However… does NUnit do something with threads?
Breakfast sounds good right about now.