JavaCodingNerd

Java Coding Nerd. This Blog will feature content-rich articles, tutorials and own opinions on variuos programming related topcis.

Testing, Uncategorized

Basics of mocking JUnit tests with Mockito

Mockito

Mockito

Why do we need to mock?

Mocking objects is a fundamental task when writing JUnit tests. There are several tools that give you the power of mocking. In my humble opinion the best one ist Mockito.

Mocking is a concept that is very hard to understand when you use it the first time because it has a certain level of abstraction. We dont create objects anymore which we test, we mock them. This means the mock will be an imposter of the original object but we have much more controll over it.
The best way to underst what mocking really means is an example, so lets go straight forward.

What you need

  • A simple Maven
  • JUnit 4
  • Mockito

Add the JUnit 4 and JUnitParams dependency to your pom.xml

<dependencies>
    <!-- https://mvnrepository.com/artifact/junit/junit -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.mockito/mockito-all -->
    <dependency>
      <groupId>org.mockito</groupId>
      <artifactId>mockito-all</artifactId>
      <version>1.10.19</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

In src/main/java create 2 interfaces. One calles Mammal and one named Food.

Later we will use this interfaces to create our mocks. Here you can already see how powerful Mockito is, you can work with mocks of interfaces without the need of a concrete object behind it. Those 2 interfaces is all we need.

public interface Mammal {

  Mammal givingBirth();
  boolean isHungry();
  void eatSomeFood(Food food);
}
public interface Food {	
  String getNutirtion();
}

I think the methods are pretty self explanatory so we don´t need to go into detail about them. I mean they aren´t what we are here for anyway

Using Mockito

First create a test class in src/test/java called MammalTest.

So the first thing we will do ist create a mock of our Mammal interaface.  And write a simple test just to verify that our mock REALLY is an Animal. This is nonsense in a real world scenario but quite good to explain how Mockito works

public class MammalTest {

  private Mammal mammal = Mockito.mock(Mammal.class);

  @Test
  public void testIfMammalIsAMammal() {
    Assert.assertTrue(mammal instanceof Mammal);
  }

 
}

Run the test by clicking right on the AnimalTest class and select Run As -> JUnit Test or use the Eclipse shortcut (alt +shift +x ) +t. You have to release the keys in brackets before you press t. Also you need to be in MammalTest.
The test case is green and we are happy.
We created our first mock and verified that it is a mammal

So what will this mock do if we use its methods? It will return default values. False for boolean, 0 for int and null for a Object. Lets write a nonsense test again just to prove it.

@Test
public void testDefaultBehaviourOfMammal() {
    Assert.assertNull(mammal.givingBirth());
  }

Ok lets get more specific. The wonderful thing about Mockito is we can give our mock a specific behaviour.  To verifiy that this is actually possible lets compare the return value of the isHungry method before we give it a certain behaviour and after.

Adding some behaviour

@Test
  public void aLivingAnimalShouldBeHoungry() {

    Assert.assertFalse("By default it will return false", mammal.isHungry());
    Mockito.when(mammal.isHungry()).thenReturn(true);
    Assert.assertTrue("After we tell the Animal to be hungry it is", mammal.isHungry());
  }

Both assertions are true. The first because we get the default value and the second because it specified a behaviour.

Exception behavior can also be tested. For example lets have a look at the eatSomeFood(Food food)  method.  the method should throw a FoodException when null ist passed.

public class FoodException extends RuntimeException {

}

This is the Test.

@Test(expected = RuntimeException.class)
  public void whenMammalIsEatingANullAFoodExceptionShouldBeThrown() {
    
    Mockito.doThrow(new FoodException()).when(mammal).eatSomeFood(null);
    mammal.eatSomeFood(null);
    
  }

First we tell our mammal what it should do when eatSomeFood is invoked with null as a parameter. Mockito makes it very easy to read what we ware mocking.
Next we actually call eatSomeFood(null). Above the method you can see that we exprect a RuntimeExcption so the test will only turn green if it throws one. Since FoodException extends RuntimeException the test will pass.

The last important thing to understand the basics of Mockto is that you can check wether a method has been called or not. To do so you Mockito.verify

@Test
  public void verifyTheAnimalGaveBirth()
  {
    mammal.givingBirth();		
    Mockito.verify(mammal).givingBirth();
  }

Conclusion

By now you sould have an idea what mockito is about. There will be more tutorials which concentrate an more specific use cases but it is very important that you understand the fundamentals of mockito first.

Spread the love

Leave a Reply

Theme by Anders Norén