0

问题:运行单元测试时,Application.Current 在类中为空。

解决方法:创建一个将运行我的测试类的应用程序域。应用程序域将为我的测试类提供一个调度程序。

代码示例:

        MyClassInTheAssembly myClass;
        string path = @"C:\\pathToTheDll\\MyAssembly.dll";
        path = path.Replace(@"\\", @"\");
        AppDomainSetup setup = new AppDomainSetup { PrivateBinPath = path };
        AppDomain domain = AppDomain.CreateDomain("MyDomain", null, setup);

        myClass = (MyClassInTheAssembly)domain.CreateInstanceFromAndUnwrap(path, typeof(MyClassInTheAssembly).FullName);

myClass 对象可用于对使用 Application.Current.Dispatcher 的任何公共方法进行单元测试。

在 myClass 上执行单元测试时收到以下错误:

找不到类型“MyAssembly.MyClassInTheAssembly”的构造函数。

调用 domain.CreateInstanceFromAndUnwrap() 方法来创建我的测试类的实例时会生成此错误。

MyClassInTheAssembly 构造函数有两个必需参数。是否可以使用参数创建类的 AppDomain 实例?

更新 感谢 user779967 为我指明了正确的方向。我上面的问题的答案是对 AppDomain.CreateInstanceFromAndUnwrap() 使用方法覆盖。我尝试使用方法覆盖来使用 AppDomain 创建我的测试类的实例:

        object[] parameters = new object[2];  // object array to pass my required parameters.
        parameters[0] = container;  // Required constructor param for myClass.
        parameters[1] = eventAggregator;  // Required constructor param for myClass.
        myClass = (MyClassInTheAssembly)domain.CreateInstanceFromAndUnwrap(path, typeof(MyClassInTheAssembly).FullName, true, BindingFlags.Default, null, parameters, null, null);

想法是使用此方法覆盖将我所需的参数传递给我的测试类的实例化。然后我可以使用从 AppDomain 派生的测试类,它为我的所有单元测试提供了一个调度线程。

执行此代码时,我收到以下 SerializationException:类型未解析成员“Castle.DynamicProxy.Serialization.ProxyObjectReference,NSubstitute,Version=1.6.1.0,Culture=neutral,PublicKeyToken=92dd2e9066daa5ca”。这是因为我需要使用 NSubstitute 对我的容器和 eventtaggregator 类进行单元测试。AppDomain 方法正在为我的构造函数参数类型而不是 NSubstitute 寻找 IUnityContainer 和 IEventAggregator 的精确参数类型匹配。

我放弃了使用 AppDomain 实例化我的测试类以进行单元测试的尝试。我决定在我的测试类方法中处理 Application.Current,如下所示:

        var dispatcher = Application.Current != null ? Application.Current.Dispatcher : Dispatcher.CurrentDispatcher;

        if (dispatcher.CheckAccess())
        {
            do something....
        }
        else dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() => CallMethodAgain())); 

在生产中运行我的代码时,Application.Current 永远不应为空。在运行我的代码进行单元测试时,我使用 Dispatcher.CurrentDispatcher 从正在执行的线程创建一个调度程序。

如果有人有一个很好的实现,可以使用 AppDomain 实例化一个用于单元测试的类,我很乐意看到它!

4

1 回答 1

0

检查 CreateInstanceAndUnwrap 这个重载版本

http://msdn.microsoft.com/en-us/library/dd387239.aspx

似乎您需要创建一个 object[] 类型的数组并用您的构造函数参数填充它。

于 2013-08-28T19:24:48.943 回答