简体   繁体   English

Moq与Unity Container单元测试

[英]Moq with Unity Container unit testing

below is an example of production code that I am trying to unit test. 下面是我试图进行单元测试的生产代码示例。 I am struggling to resolve a dependency to a concrete class that is being used. 我正在努力解决对正在使用的具体类的依赖。

public MyClass(IUnityContainer container)
{
    this.unityContainer = container;
}

public string DoWork()
{
     var sender = unityContainer.Resolve<IInterface>();  // how to setup this object
     var json = sender.Send("something");
     var value = serializer.Deserialize<SomeModel>(json);
     return value.url;
}

I want to mock out the IInterface used by this method. 我想模仿这种方法使用的IInterface。 How do I set that up in my unit test code? 如何在我的单元测试代码中进行设置? I feel like there is something missing here. 我觉得这里缺少一些东西。 this has a smell of an anti-pattern..... 这有一种反模式的气味......

this has a smell of an anti-pattern 这有一种反模式的气味

It certainly does. 当然可以。 Why are you passing an instance to your DI container into your business object's constructor? 为什么要将实例传递给DI容器到业务对象的构造函数中? You should pass the IInterface instead. 你应该通过IInterface See Dependency Injection container in constructor . 请参阅构造函数中的Dependency Injection容器

Anyway to make this work in your unit test, you just have to set up the container to return an instance or a mock of IInterface . 无论如何要在单元测试中使这个工作,你只需要设置容器来返回实例或IInterface的模拟。 Like this: 像这样:

public void MyUnitTest()
{
    IUnityContainer myContainer = new UnityContainer();
    myContainer.RegisterType<IInterface, YourInstance>();

    MyClass classUnderTest = new MyClass(myContainer);
    classUnderTest.DoWork();

    Assert...
}

See How to use Unity.RegisterType with Moq? 请参阅如何将Unity.RegisterType与Moq一起使用? to mock the YourInstance . 模拟YourInstance

I agree with CodeCaster. 我同意CodeCaster。 The typical pattern would be to accept a parameter of type IInterface in the constructor and assign it to a class-level variable. 典型的模式是在构造函数中接受IIInface类型的参数,并将其分配给类级变量。

public MyClass(IInterface sender)
{
    this.sender = sender;
}

When testing, simply pass in your moq. 测试时,只需传入你的moq。 That said, there are times when I dislike passing in a dependency through the constructor. 也就是说,有时我不喜欢通过构造函数传递依赖项。 Such as: 如:

  • I may need multiple instances of a class 我可能需要一个类的多个实例
  • The object is only needed conditionally. 只有条件地需要该对象。
  • The class's constructor may depend on additional values that are not determined until run time. 类的构造函数可能依赖于直到运行时才确定的其他值。

In those cases, passing the container as a parameter is the only solution I've come across. 在这些情况下,将容器作为参数传递是我遇到的唯一解决方案。 Just be sure to register your initial instance of the container with itself. 请务必注册容器的初始实例。 Otherwise, the DI will provide your constructor with a new (empty) container. 否则,DI将为您的构造函数提供一个新的(空)容器。 If anyone has a better pattern, particularly one that works with Unity, I'd love to see it. 如果有人有更好的模式,特别是与Unity合作的模式,我很乐意看到它。

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

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