user3240883
user3240883

Reputation: 309

Best practices with Mockito

I create mocked objects and I define some rules (when someMethod() then doSth()).

What are the best practices to make that? Create a class with such functionality returning mocked object? Or make a private static method returning mocked object ? Or make my own mocked class?

Upvotes: 3

Views: 5791

Answers (1)

slim
slim

Reputation: 41223

If you find yourself creating test classes (other than the classes containing actual tests), then you've defeated the purpose of having a mocking framework.

Create your mocks in your testcases:

 @Test
 public void testGreetingGenerator() {
      Person mockPerson = mock(Person.class);
      when(mockPerson.getName()).thenReturn("Alan");

      GreetingGenerator greeting = new GreetingGenerator(mockPerson);
      assertEquals("Hello Alan", greeting.getGreeting());
 }

If you are using the same mock in many tests, by all means make the mock a field, and put the mock creation into an @Before method.

 @Before
 public void setUp() {
      mockPerson = mock(Person.class);
      when(mockPerson.getName()).thenReturn("Alan");
 }

 @Test
 public void testGreetingGenerator() {
      GreetingGenerator greeting = new GreetingGenerator(mockPerson);
      assertEquals("Hello Alan", greeting.getGreeting());
 }

You can create a "basic" mock in setUp() and add more mocked behaviour to it in the individual testcases. Remember that setUp() gets called before each test, so you get fresh objects in each test.

If the mock creation gets too long and complex, it's fine to move it into a method (static or otherwise), and if necessary decompose that method into lots of smaller ones.

However, if your test code gets too complicated, think of it as a warning that perhaps the unit under test has too many dependencies and needs to be redesigned for testability.

Mocking is for unit testing. In the example above, the unit I am testing is GreetingGenerator. I am not intending to test Person here, so it is better to use a mock Person than a real one. That way if something about Person breaks, my Person tests will fail but my GreetingGenerator tests will keep working.

However that means that those tests don't validate that your Person and GreetingGenerator classes interoperate properly, and that's why as well as unit tests, you should have integration tests.

If you know a class is just for value objects, there's little benefit in using a mock.

Upvotes: 12

Related Questions