简体   繁体   English

具有统一容器和泛型的模拟(Moq)

[英]Mock (Moq) with unity container and generics

I have a Container interface with a generic resolve method which, when implemented, resolves using Unity. 我有一个带有通用解析方法的Container接口,该接口在实现后会使用Unity进行解析。

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

Currently there is a Mock Container class: 当前有一个模拟容器类:

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

But I want to use Moq for consistency and do the equivalent: 但是我想使用Moq来保持一致性并执行等效操作:

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

But I get 2 compile errors 'T' could not be found 但是我'T' could not be found 2个编译错误'T' could not be found

Is the Moq syntax wrong, am I missing a reference or can this just not be done? Moq语法是否错误,我是否缺少参考文献?还是不能这样做?

Edit I know that mocking the container is not ideal. 编辑我知道嘲笑容器并不理想。 I could resolve each class one-by-one in my setup code. 我可以在设置代码中一对一地解析每个类。

My question is whether there is some Moq syntax to perform the equivalent of my actual container. 我的问题是是否有某种Moq语法可以执行与我的实际容器等效的操作。

You usually can't do this (set up generic methods without specifying a type), but if you only want to return default(T) and don't care if the function is called at all, it's enough to simply create the mock without calling Setup : 您通常无法做到这一点(在不指定类型的情况下设置泛型方法),但是如果您只想返回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)

You can even return mocks instead of default(T) by changing the DefaultValue property of the mock from DefaultValue.Empty to DefaultValue.Mock . 你甚至可以返回嘲笑而不是default(T)通过改变DefaultValue模拟的物业DefaultValue.EmptyDefaultValue.Mock

You don't need to derive a mock object from your interface. 您无需从接口派生模拟对象。 So get rid of MockContainer. 因此,摆脱MockContainer。

In your unit test you should at that point know what types you want to test. 在单元测试中,此时您应该知道要测试的类型。 So at that point, just give it a real type and tell it what to return. 因此,到那时,只需给它一个实类型并告诉它要返回什么即可。

ie

//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);

Why would you mock the container? 你为什么要嘲笑容器? This is more of an integration concern. 这更多地是集成问题。 All of your code should be testable without having a container wire them up. 您的所有代码都应可测试,而无需使用容器将它们连接起来。 Mocking the container to return a dependency which you are then passing in to consuming classes seems like a big waste of time to me. 模拟容器以返回依赖关系,然后将其传递给使用类,这对我来说似乎是浪费时间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM