'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. 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.....
Solution 1:[1]
This is the "service locator" antipattern, where you inject your dependency injection container / inversion of control into your logic.
You should pass the IInterface
that it depends on instead, so that you control what instances it can otain. See Dependency Injection container in constructor.
If you can't refactor the class, you have to injecting the container in your unit test. Set up the container to return an instance (or rather, a mock) of 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? to mock the YourInstance
.
Solution 2:[2]
I agree with CodeCaster. The typical pattern would be to accept a parameter of type IInterface in the constructor and assign it to a class-level variable.
public MyClass(IInterface sender)
{
this.sender = sender;
}
When testing, simply pass in your 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. If anyone has a better pattern, particularly one that works with Unity, I'd love to see it.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Jack Whipnert |