Reputation: 5043
I have some methods in the code base that rely on Application.Current.Dispatcher.Invoke... to make sure things run on the GUI thread. I am currently trying to write unit tests for these methods but (as expected) Application.Current is null so I'm getting a NullReferenceException.
I tried to run the affected tests in their own AppDomain as suggested here: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/786d5c06-0511-41c0-a6a2-5c4e44f8ffb6/
But Application.Current is still null when I do that. Shouldn't starting up an AppDomain set the Application.Current for me? Why is it still null?
My code: The base class:
[TestClass()]
[Serializable]
public class UnitTest
{
protected void ExecuteInSeparateAppDomain(string methodName)
{
AppDomainSetup appDomainSetup = new AppDomainSetup();
appDomainSetup.ApplicationBase = Environment.CurrentDirectory;
AppDomain appDomain = AppDomain.CreateDomain(methodName, null, appDomainSetup);
try
{
appDomain.UnhandledException += delegate(object sender, UnhandledExceptionEventArgs e)
{
throw e.ExceptionObject as Exception;
};
UnitTest unitTest = appDomain.CreateInstanceAndUnwrap(GetType().Assembly.GetName().Name, GetType().FullName) as UnitTest;
MethodInfo methodInfo = unitTest.GetType().GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance);
if (methodInfo == null)
{
throw new InvalidOperationException(string.Format("Method '{0}' not found on type '{1}'.", methodName, unitTest.GetType().FullName));
}
try
{
methodInfo.Invoke(unitTest, null);
}
catch (System.Reflection.TargetInvocationException e)
{
throw e.InnerException;
}
}
finally
{
AppDomain.Unload(appDomain);
}
}
}
The calling unit test (contained in a class that inherits from UnitTest):
[TestMethod()]
public void QualifierViewModel_FlagsAndLoadDatasets()
{
ExecuteInSeparateAppDomain("TestLoadDataSets");
}
Upvotes: 9
Views: 7796
Reputation: 1
This workaround works for me:
[TestClass]
public class MockAppTests
{
private static Application application = new Application() { ShutdownMode= ShutdownMode.OnExplicitShutdown };
}
[TestClass]
public class IntegrationTests : MockAppTests
{
[TestMethod]
public void MyTest()
{
//test
}
}
Upvotes: 0
Reputation: 5043
So for now I have a nasty workaround. I basically moved all the tests that are testing methods that use Application.Current to a single test (so they will all be on the same thread) and call new Application().
The nasty code:
[TestClass]
public class IntegrationTests
{
private CedarFile testCedarFile;
/// <summary>
/// This test tests methods that utilize Application.Current.
/// They all have to be in the same test because they must run on the same thread to use the Application instance.
/// </summary>
[TestMethod]
public void IntegrationTests_All()
{
new Application();
QualifierViewModel_FlagsAndLoadDatasets();
CurrentFilesViewModel_AddCedarFile();
CurrentFilesViewModel_AddCedarFileReadOnly();
}
... the private methods to test ...
}
Upvotes: 14
Reputation: 4172
Try to remove the Serializable
attribute and instead derive the UnitTest
class from MarshalByRefObject
.
Upvotes: -1