首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对于单元测试,Application.Current为空

对于单元测试,Application.Current为空
EN

Stack Overflow用户
提问于 2012-09-28 00:21:50
回答 3查看 6.9K关注 0票数 8

我在代码库中有一些依赖于Application.Current.Dispatcher.Invoke的方法……以确保程序在GUI线程上运行。我目前正在尝试为这些方法编写单元测试,但是(不出所料) Application.Current为空,所以我得到了一个NullReferenceException。

我尝试按照这里的建议在它们自己的AppDomain中运行受影响的测试:http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/786d5c06-0511-41c0-a6a2-5c4e44f8ffb6/

但是当我这样做的时候,Application.Current仍然是空的。启动AppDomain不应该为我设置Application.Current吗?为什么它仍然是空的?

我的代码:基类:

代码语言:javascript
复制
[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);
        }
    }
}

调用单元测试(包含在从UnitTest继承的类中):

代码语言:javascript
复制
[TestMethod()]
public void QualifierViewModel_FlagsAndLoadDatasets()
{
    ExecuteInSeparateAppDomain("TestLoadDataSets");
}
EN

回答 3

Stack Overflow用户

发布于 2012-09-28 03:53:03

所以现在我有一个糟糕的变通办法。基本上,我将使用Application.Current的测试方法的所有测试移到一个测试中(因此它们都在同一个线程上)并调用new Application()。

令人讨厌的代码:

代码语言:javascript
复制
[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 ...
}
票数 13
EN

Stack Overflow用户

发布于 2014-07-11 19:05:24

此解决方法适用于我:

代码语言:javascript
复制
[TestClass]
public class MockAppTests
{
    private static Application application = new Application() { ShutdownMode= ShutdownMode.OnExplicitShutdown };
}

[TestClass]
public class IntegrationTests : MockAppTests
{        
    [TestMethod]
    public void MyTest()
    {
        //test
    }
}
票数 0
EN

Stack Overflow用户

发布于 2012-09-28 00:42:42

尝试删除Serializable属性,改为从MarshalByRefObject派生UnitTest类。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12625848

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档