Let's say I have two methods, one of which is basically a wrapper for the other method with just a tiny bit of extra processing:
public class ItemRepositoryImpl implements ItemRepository {
...
@Override
public void delete(UUID itemID) {
Item item = findOne(itemID);
delete(item);
}
@Override
public void delete(Item item) {
// Do a bunch of stuff that needs a lot of tests run on it, like
// deleting from multiple data sources etc
...
}
}
What is wrong with writing a unit test for the delete(UUID) method that partially mocks ItemRepositoryImpl, and checks that delete(UUID) eventually calls delete(Item)? If I did this, I would not have to write a bunch of duplicate tests for each delete method!
In Mockito, I could implement such a test with a spy like this:
ItemRepository spyRepo = spy(repository); // Create the spy
when(spyRepo.findOne(itemID)).thenReturn(item); // Stub the findOne method
doNothing().when(spyRepo).delete(item); // Stub the delete(Item) method
spyRepo.delete(itemID); // Call the method under test
// Verify that the delete(Item) method was called
verify(spyRepo).delete(item);
However, the Mockito documentation strongly discourages the use of this type of partial mocking, basically stating that it should only be used on interim legacy code and 3rd party APIs. What would be better solution?
If you are doing a pure unit test and your unit of test is a method then I would say that there is nothing wrong with what you have mocked here. Some will argue that unit tests should take a more black box approach and that by mocking method calls, your test knows too much about the implementation of the method under test.
If your unit under test is a class rather than a method then you could simply mock calls to other classes.
There is always debate around unit tests. Here is an interesting article on the subject which is very relevant to your question: http://martinfowler.com/articles/mocksArentStubs.html