8

コードベースには、GUIスレッドで実行されることを確認するためにApplication.Current.Dispatcher.Invoke...に依存するメソッドがいくつかあります。現在、これらのメソッドの単体テストを作成しようとしていますが、(予想どおり)Application.Currentがnullであるため、NullReferenceExceptionが発生します。

http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/786d5c06-0511-41c0-a6a2-5c4e44f8ffb6/で提案されているように、影響を受けるテストを独自のAppDomainで実行しようとしました。

しかし、それを行ってもApplication.Currentはnullのままです。AppDomainを起動して、Application.Currentを設定するべきではありませんか?なぜまだnullなのですか?

私のコード:基本クラス:

[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から継承するクラスに含まれています):

[TestMethod()]
public void QualifierViewModel_FlagsAndLoadDatasets()
{
    ExecuteInSeparateAppDomain("TestLoadDataSets");
}
4

3 に答える 3

13

だから今のところ、私は厄介な回避策を持っています。基本的に、Application.Current を使用するメソッドをテストしているすべてのテストを 1 つのテストに移動し (したがって、それらはすべて同じスレッド上にあります)、new Application() を呼び出します。

厄介なコード:

[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 ...
}
于 2012-09-27T19:53:02.747 に答える
0

この回避策は私にとってはうまくいきます:

[TestClass]
public class MockAppTests
{
    private static Application application = new Application() { ShutdownMode= ShutdownMode.OnExplicitShutdown };
}

[TestClass]
public class IntegrationTests : MockAppTests
{        
    [TestMethod]
    public void MyTest()
    {
        //test
    }
}
于 2014-07-11T11:05:24.213 に答える
-1

属性を削除して、代わりにからクラスをSerializable派生させてください。UnitTestMarshalByRefObject

于 2012-09-27T16:42:41.833 に答える