Mock service (Spring Boot)

Introduction

It explains how to create and use a mock.


When to use a mock?

There are times when it is not possible to count on the proper functioning of the actual implementations of business services or other services from other layers of the application. For example, a business service that uses infrastructure elements, such as a remote web-service, that are only available from the deployed infrastructure but not on the local development environment or while running the unit tests on the deployment pipeline.


In these cases we can use a mock of this service. A mock is an alternative implementation of the service interface that internally will probably have a little complex logic, but which, considered as a black box, is consistently functional with the actual implementation.

How to implement a mock?

To make it possible to exchange some implementations for others, interfaces are defined.

Let's create a mock implementation of the interface MyService of the application business logic:

public class MyServiceMockImpl implements MyService {

@Override

public Long generateRandom() {

SecureRandom secureRandom = SecureRandom.getInstance("NativePRNG");

return secureRandom.nextLong();

}

}


How to configure the IoC Spring container for instantiating the mock under certain conditions?

Spring provides two annotations that allow you to condition when instantiating the actual implementation or mock:

@Conditional, since Spring 4

@Profile, since Spring 3


Reference and examples:

  • Condition annotations

https://riptutorial.com/spring/example/30841/condition-annotations

  • The Spring @ConditionalOnProperty Annotation

https://www.baeldung.com/spring-conditionalonproperty


@ConditionalOnProperty

The @ConditionalOnProperty annotation allows configuration to be included based on a Spring Environment property. Use the prefix and name attributes to specify the property that should be checked. By default any property that exists and is not equal to false will be matched. You can also create more advanced checks using the havingValue and matchIfMissing attributes.

Samples:

@ConditionalOnProperty(value='somebean.enabled', matchIfMissing = true, havingValue="yes")

@ConditionalOnProperty(prefix = "notification", name = "service")

@ConditionalOnProperty(prefix = "notification", name = "service", havingValue = "sms")