【问题标题】:NUnit TestFixture with no-arg constructors具有无参数构造函数的 NUnit TestFixture
【发布时间】:2015-06-16 13:04:55
【问题描述】:

如何解决您尝试定义的 TestFixture 需要引用没有无参数构造函数的类型的情况?

我正在尝试测试具有多个实现的接口。从 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 等没有无参数构造函数,因此当 NUnit 尝试发现可用的测试用例时,我收到此错误(并且测试未显示在 VS 中):

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

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

【问题讨论】:

    标签: c# unit-testing nunit


    【解决方案1】:

    您可以使用dependency injection container 为您实例化它们,而不是使用new T() 来实例化您的对象。下面是一个使用微软 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>();   
    }
    

    【讨论】:

    • -实际上不是 _impl = new T();这就是问题所在,而似乎是导致问题的 TestFixture 上的 typeof 属性。
    • 您是否尝试过删除 new() 通用约束以及对 new() 的调用?即其中 T : IMyInterface { ...
    【解决方案2】:

    正如@Steve Lillis 在他的回答中所说,您需要停止使用new T()。当你这样做时,你不需要在你的泛型上使用new 约束。一种选择是使用 IOC 容器,例如 Steve 建议的 Castle Windsor / Unity 来解决安装程序中的依赖关系。

    您还没有说您的实现的构造函数采用什么参数,但如果它们都相同,那么替代方法是使用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 });
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多