I have a consumer class responsible for consuming a string and deciding what to do with it. It can either parse and insert the parse data in a database or notify an administrator.
Below is my implementation.
public void Consume(string email)
{
if(_emailValidator.IsLocate(email))
{
var parsedLocate = _parser.Parse(email);
// Insert locate in database
}
else if(_emailValidator.IsGoodNightCall(email))
{
// Notify email notifying them that a locate email requires attention.
_notifier.Notify();
}
}
Below is my unit test.
// Arrange
var validator = new EmailValidator();
var parser = new Mock<IParser>();
var notifier = new Mock<INotifier>();
var consumer = new LocateConsumer(validator, parser.Object, notifier.Object);
var email = EmailLiterals.Locate;
// Act
consumer.Consume(email);
// Assert
parser.Verify(x => x.Parse(email), Times.Once());
Is it code smell to mix mocks and real implementation in unit tests? Also, how do always having to test whether method abc()
always ran once? It doesn't seem right that once I add a new unit test every time I add a function inside my if
block. Seems like if I continue adding to my Consume
method I'm create a trap.
Thank you.
Mock Objects are a Code Smell But mock objects are more often smelly because they are telling you something about the system under test. A Code Smell is defined as “a hint that something has gone wrong somewhere in your code”.
Test smells are defined as bad programming practices in unit test code (such as how test cases are organized, implemented and interact with each other) that indicate potential design problems in the test source code [3], [4], [5], [6].
What is mocking? Mocking is a process used in unit testing when the unit being tested has external dependencies. The purpose of mocking is to isolate and focus on the code being tested and not on the behavior or state of external dependencies.
Only use a mock (or test double) “when testing things that cross the dependency inversion boundaries of the system” (per Bob Martin). If I truly need a test double, I go to the highest level in the class hierarchy diagram above that will get the job done. In other words, don't use a mock if a spy will do.
To be nitpicking, a unit test is an automated test that tests a unit in isolation. If you combine two or more units, it's not a unit test any more, it's an integration test.
However, depending on the type of units you integrate, having lots of that type of integration tests may be quite okay.
Krzysztof Kozmic recently wrote a blog post about this where he describes how Castle Windsor has very few unit tests, but lots of integration tests. AutoFixture also has a large share of those types of integration tests. I think the most important point is that as a general rule the integration must not cross library boundaries.
In any case you can view the actual implementation as an extreme end of the Test Double Continuum, so just as there are scenarios where it makes sense to use Stubs, Mocks, Spies, or Fakes, there are also scenarios where the actual implementation may make sense.
However, just keep in mind that you are no longer testing the unit in isolation, so you do introduce a coupling between the units that makes it more difficult to vary each independently.
To conclude, I still consider it a smell because it should always be an occasion to stop and think. However, a smell indicates no more than that, and sometimes, once you've thought it over, you can decide to move along.
I would say a strong yes. Unit testing should be free of dependencies among components.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With