问题:运行单元测试时,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 实例化一个用于单元测试的类,我很乐意看到它!