Tarion
Tarion

Reputation: 17134

Using Moq, do I always need to mock all dependencies?

I had the following line in over 100 of my tests:

var registry = new Mock<ObjectRegistry>(new List<Assembly>()).Object;

A little refactoring changed my ObjectRegistry constructor to:

public ObjectRegistry(AssemblyRegistry assemblies, UserPromt userPromt)

So I have to update all my 100 Testcases to use the following mock instead:

var objectRegistry = new Mock<ObjectRegistry>(Mock.Of<AssemblyRegistry>(), Mock.Of<UserPromt>());

And all I want is that all dependencies are mocked, invariant no matter what dependencies I need.

Can I tell Moq somehow to mock all dependencies it needs automatically?

In java with Mockito this would not be an issue at all ...

Upvotes: 2

Views: 1342

Answers (2)

amirhosseinab
amirhosseinab

Reputation: 1050

The best practice for your problem is to use Interfaces instead of concrete classes and pass your dependencies by those interfaces.

public ObjectRegistry(IAssemblyRegistry assemblies, IUserPromt userPromt)

Upvotes: 1

Finglas
Finglas

Reputation: 15709

You are mocking a concrete object here. Moq works best when used with an interface. Try to mock roles, not objects (pdf). For example, introduce an interface such as IObjectRegistry. At present your code knows it is dealing with an ObjectRegistry, when ideally you should be able to switch your implementation out whenever you wish. Providing you have an abstraction in place. It would be ideal both for testability and programming best practices to "program to an interface" instead. Note interface here does not necessarily mean an interface in terms of C#/Java etc.

var registry = new Mock<IObjectRegistry>();

public class ObjectRegistry : IObjectRegistry { // Snip }

Then use this. As this is an interface, you can freely change the concrete (real/production) class and its constructor as you wish. Your tests and the rest of the system should be unaware. If the registry had one method on the interface such as GetObject your system should simply rely on this abstraction, not the fact it is working with an ObjectRegistry instance.

Currently your code is actually creating a real instance of an ObjectRegistry, then stubbing/mocking the methods in question. This is not ideal in most cases.

Upvotes: 3

Related Questions