带有无参数构造函数的NUnit TestFixture

时间:2015-06-16 13:04:55

标签: c# unit-testing nunit

如何解决您尝试定义的TestFixture需要引用没有no-arg构造函数的类型的场景?

我试图测试具有多个实现的接口。从NUnit文档中可以看出如何使用这样的泛型设置(我可以定义多种实现类型):

[TestFixture(typeof(Impl1MyInterface))]
[TestFixture(typeof(Impl2MyInterface))]
[TestFixture(typeof(Impl3MyInterface))]
public class TesterOfIMyInterface<T> where T : IMyInterface, new() {

    public IMyInterface _impl;

    [SetUp]
    public void CreateIMyInterfaceImpl() {
        _impl = new T();
    }
}

问题出现是因为Impl1MyInterface,Impl2MyInterface等没有no-arg构造函数所以当NUnit尝试发现可用的测试用例时我得到了这个错误(并且测试没有出现在VS中):

  

异常System.ArgumentException,异常抛出发现测试   在XYZ.dll中

有办法解决这个问题吗?定义no-arg构造函数没有意义,因为我的代码需要这些值才能工作。

2 个答案:

答案 0 :(得分:0)

您可以使用new T()为您实例化它们,而不是使用dependency injection container来实例化您的对象。以下是使用Microsoft Unity的示例:

[SetUp]
public void CreateIMyInterfaceImpl() {
    var container = new UnityContainer();

    // Register the Types that implement the interfaces needed by
    // the Type we're testing.
    // Ideally for Unit Tests these should be Test Doubles.
    container.RegisterType<IDependencyOne, DependencyOneStub>();
    container.RegisterType<IDependencyTwo, DependencyTwoMock>();

    // Have Unity create an instance of T for us, using all
    // the required dependencies we just registered
    _impl = container.Resolve<T>();   
}

答案 1 :(得分:0)

正如@Steve Lillis在回答中所说,你需要停止使用new T()。执行此操作时,您不需要在通用上使用new约束。一种选择是使用IOC容器,如Castle Windsor / Unity,因为Steve建议解决安装程序中的依赖关系。

您还没有说明您的实现构造函数采用了哪些参数,但如果它们完全相同,则替代方法是使用Activator.CreateInstance。因此,如果您的构造函数都使用整数和字符串,那么您的代码将如下所示:

[TestFixture(typeof(Impl1MyInterface))]
[TestFixture(typeof(Impl2MyInterface))]
[TestFixture(typeof(Impl3MyInterface))]
public class TesterOfIMyInterface<T> where T : IMyInterface {

    public IMyInterface _impl;

    [SetUp]
    public void CreateIMyInterfaceImpl() {
        int someInt1 = 5;
        string someString = "some value";
        _impl = (T)Activator.CreateInstance(typeof(T), new object[] { someInt1, someString });
    }
}