Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practices for unit tests, mock objects, and ioc

Okay so I have been trying to get into IoC lately. However, I keep running into one hurdle - that is the fact that I love using mock objects.

They are quick and painless to setup.

However, if I use IoC all over the place in my code then it forces me to create test implementations (and configurations) of my objects instead of using mock objects (ie. using moq).

The end result is that I end up with enormous configuration files for testing.

In addition there are many scenarios in testing where I require different behaviors out of my classes on a test-to-test basis. With moq objects this is extremely easy. How would you do something similar with IoC?

Any help would be much appreciated.

Thanks,
Mike

like image 464
devlife Avatar asked Nov 08 '09 23:11

devlife


People also ask

What is a mock object in unit testing?

Mock - A mock object is a fake object in the system that decides whether or not a unit test has passed or failed. A mock starts out as a Fake until it's asserted against.

What are the best practices for unit testing?

The best practices for unit testing are debated topics in the industry. In practice, however, projects and teams should align on key concepts in order to foster code consistency and ease-of-maintenance.

Should we mock the external services in unit tests?

Although unit tests concentrate on specific and smaller pieces of code, there is a chance that the code is dependent on external services for some logic. Therefore, we should mock the external services and merely test the logic and execution of our code for varying scenarios.

What are the advantages of using mock objects?

Using mock objects makes it easy to write a more focused and cheap test code when our production code has a non-deterministic outside dependency. For example, we mock a repository class that finds orders of a customer by status in the test code below: Using mocks is not a silver bullet, and overusing mocking can cause some problems.


1 Answers

IoC should make using mock objects easier, not harder.

Several IoC Container frameworks will allow you to define pre-existing objects to inject; with Moq you'd just set it up for myMockObject.Object.

EDIT: Example of configuring Unity with a mock:

var mockService = new Mock<IMyService>();
container.RegisterInstance<IMyService>(mockService.Object);

As an alternative, you can just pass the mock object into the constructor of the class under test (for constructor injection) and bypass the IoC container entirely in your unit tests.

EDIT: Josh's answer is a good example of the alternative. I would generally go with his solution rather than reconfiguring the container.

like image 189
TrueWill Avatar answered Sep 23 '22 01:09

TrueWill