method.CreateInstance()实际调用的代码是这样的:
publicobjectCreateInstance() { returnActivator.CreateInstance(method.ReflectedType); } |
一看代码就知道为什么只支持无参的构造函数。
看到瓜,就容易找到解决方法,既然在testClass==null时才会创建测试类的实例,如果我们通过IoC容器在这个方法执行前创建testClass的实例并传递LifetimeCommand.Execute方法,不就可以解决问题了吗?
所以,继续顺藤摸瓜,找出在哪里调用了LifetimeCommand.Execute(objecttestClass)方法。。。
在Xunit.Sdk.TestClassCommandRunner.Execute()中找到:
MethodResultmethodResult=command.Execute(testClassCommand.ObjectUnderTest:; |
testClassCommand的类型是ITestClassCommand接口,该接口的实现是Xunit.Sdk.TestClassCommand,看看它的ObjectUnderTest属性:
public object ObjectUnderTest { get { return null; } } |
只要这里从IoC容器返回测试类的实例,就可以实现依赖注入了。
进入解决方案...
注:解决方案不需要修改任何xUnit.net的源代码。
在单元测试项目中创建一个实现ITestClassCommand接口的IocTestClassCommand类,代码如下:
publicclassIocTestClassCommand:ITestClassCommand { TestClassCommand_testClassCommand; publicIocTestClassCommand() :this((ITypeInfo)null){ } publicIocTestClassCommand(TypetypeUnderTest) :this(Reflector.Wrap(typeUnderTest)){ } publicIocTestClassCommand(ITypeInfotypeUnderTest) { _testClassCommand=newTestClassCommand(typeUnderTest); } publicobjectObjectUnderTest { get{returnIoCFactory.Instance.CurrentContainter. Resolve(_testClassCommand.TypeUnderTest.Type);} } publicRandomRandomizer { get{return_testClassCommand.Randomizer;} set{_testClassCommand.Randomizer=value;} } publicITypeInfoTypeUnderTest { get{return_testClassCommand.TypeUnderTest;} set{_testClassCommand.TypeUnderTest=value;} } [SuppressMessage(“Microsoft.Design”,“CA1062:Validateargumentsofpublicmethods”, MessageId=“0”,Justification=“Thisparameterisverifiedelsewhere.”)] publicintChooseNextTest(ICollection<IMethodInfo>testsLeftToRun) { return_testClassCommand.Randomizer.Next(testsLeftToRun.Count); } publicExceptionClassFinish() { return_testClassCommand.ClassFinish(); } publicExceptionClassStart() { return_testClassCommand.ClassStart(); } publicIEnumerable<ITestCommand>EnumerateTestCommands(IMethodInfotestMethod) { return_testClassCommand.EnumerateTestCommands(testMethod); } publicIEnumerable<IMethodInfo>EnumerateTestMethods() { return_testClassCommand.EnumerateTestMethods();}publicboolIsTestMethod(IMethodInfotestMethod) { return_testClassCommand.IsTestMethod(testMethod); } } |