Site Loader
mocking

Unit testing can be explained as verification on the code segment. A unit test needs to be verified as an isolated piece of code to get a predictable result. This code segment will be evaluated based on different behaviours of the code segment as well as it’s functional behaviour.

Mocking is primarily used in unit testing. A code segment can depend on the usage of an external party such as a service, provider or database connection when executing the code block. You need to replace the other dependency by mocks that simulate the behaviour of the real objects to isolate the execution of the code segment. This is useful when the real dependencies are hard to combine into the unit test.

In short, mocking is creating objects that simulate the behaviour of real objects/dependencies. These dependency usages can be partitioned into two main categories.

  1. Response predictable dependency usages
  2. Response unpredictable dependency usages

Response predictable dependency usages

The results provided by this kind of dependencies will not be changed based on the executing environment. Let’s check an example of response predictable dependencies.

   
public boolean isValidEmail(String email) {
  Pattern pattern = Pattern.compile("^.+@.+\\..+$");
  Matcher matcher = pattern.matcher(email);

  return matcher.find();
}
 

Above piece of code uses Pattern and Matcher from Java. When we provide the same input in hundreds of execution environments we will get the same response. That means the response we got from the external dependencies didn’t change. This kind of scenarios doesn’t need mocking unless if there is a special concern on the result or that functionality is not implemented at the time of writing this unit test.

Response unpredictable dependency usages

The results provided by this kind of dependencies will be change based on the executing environment. A simple example of this kind of dependency is a service which fetches data from the database. When we provide some ids to get the data the result will be provided based on the data available on executing environment. Let’s check an example of response unpredictable dependencies.

  
public List<PackedFruit> getFruits(List<String> ids) {
  List<Fruit> fruits = fruitService.getFruits(ids);
  Map<String, Double> pricesMap = priceService.getPricing(ids);
  
  return users.stream().map(fruit -> {
    return createPackedFruit(fruit, pricesMap.get(fruit.getId()))
  }).collect(Collectors.toList());
}
  

In the above code segment, we cannot guarantee that we will get the same response every time we give a list includes “500” to FruitService#getFruits(List<String>) and PriceService#getPricing(List<String>) on all environments. When we are having database calls within the test, may cause the failure of the test due to unavailability of the database server. This is a place where mocking come to rescue your unit test.

There is one more type of dependencies. It is dependencies which handle a separate concern apart from the scope of the functionality you are going to test. That dependency usage is required to execute the code but that is located outside of our scope. Let’s check an example of a scenario like that. In scenarios like below Mocking will come to rescue the isolated execution of your unit test.

Check below code segment.

    
public List<Fruit> getHealthyFruits(List<Fruit> fruitsToFilter) {
    return fruitsToFilter.stream().filter(fruit -> fruitService.isHealthyForKids(fruit))
        .filter(fruit -> fruitService.isHealthyForPatients(fruit)).collect(
            Collectors.toList());
}

Here we have used FruitService#isHealthyForKids(List<Fruit>) and FruitService#isHealthyForPatients(List<Fruit>). Let’s think these methods do not include database calls or any other third party service access. Even though the way of filtering the fruits is known in the first place, in order to test this piece of code as an isolated part we don’t need to depend on FruitService.

This is a place we need to mock FruitService. Even though the way of filtering is changed later for the verification of this code segment will not be changed since we have no dependency over FruitService.

Now you have an idea when to use mocks. Let’s check the way we write mocks. For Java, there is a library called Mockito for this tutorial and PowerMock. For other languages like Javascript, mocking comes with testing libraries such as Jasmine, Karma, Mocha and mocking can be enabled with libraries like Sinon. Since mocking is a must-have feature for Unit testing each language must have separate libraries or built-in support for mocking.

This what I thought of sharing on this article. Let me know if this was useful to you ?

Happy Coding!

Leave a Reply

Your email address will not be published.