模拟(Moq)与统一容器和泛型

时间:2014-06-25 11:19:40

标签: c# unit-testing generics moq unity-container

我有一个带有通用解析方法的Container接口,当实现时,使用Unity解析。

public interface IContainer
{
    T Resolve<T>();
}

目前有一个模拟容器类:

public class MockContainer : IContainer {
    public T Resolve<T>()
    {            
        return default(T);
    }
}

但我想使用Moq来保持一致性并做同等的事情:

mockContainer
    .Setup(container => container.Resolve<T>())
    .Returns(default(T));

但我得到2个编译错误'T' could not be found

Moq语法是错误的,我是否错过了引用,或者这是不是可以做到?

修改 我知道嘲弄容器并不理想。我可以在设置代码中逐个解析每个类。

我的问题是是否有一些Moq语法来执行相当于我的实际容器。

3 个答案:

答案 0 :(得分:1)

你通常不能这样做(在没有指定类型的情况下设置泛型方法),但是如果你只想返回default(T)而不关心函数是否被调用,那么它就足够了在不调用Setup的情况下创建模拟:

var mockZincContainer = new Mock<IContainer>();

// works just fine
mockZincContainer.Object.Resolve<DateTime>(); // returns default(DateTime)
mockZincContainer.Object.Resolve<object>(); // returns default(object)

您甚至可以通过将模拟的default(T)属性从DefaultValue更改为DefaultValue.Empty来返回模拟而不是DefaultValue.Mock

答案 1 :(得分:0)

您不需要从界面派生模拟对象。所以摆脱MockContainer。

在您的单元测试中,您应该知道要测试的类型。所以在这一点上,只需给它一个真实的类型并告诉它要返回什么。

//arrange
mockZincContainer
    .Setup(container => container.Resolve<ISomeInterface>())
    .Returns(new ConcreteClassThatDerivesFromSomeInterface());
var testClass = new ClassToBeTested(mockZincContainer.Object);

//act
testClass.DoYourMethod();

//assert
mockZincContainer.Verify(c => c.Resolve<ISomeInterface>(), Times.Once);

答案 2 :(得分:0)

你为什么要嘲笑容器?这更像是一种整合问题。所有代码都应该是可测试的,而不需要容器连接它们。模拟容器以返回依赖关系,然后将其传递给使用类似乎对我来说是一个很大的浪费时间。