Unit testing of Spring Service with constructor dependencies
Constructor based dependency injection is the recommended way to use dependency injection in Spring. In this post I'm going to demonstrate how to write unit test of a service class which has dependencies on other beans e.g. repositories.
Let's assume our service class is like the following:
@Service
class MyService {
private final UserRepository userRepository;
private final AddressRepository addressRepository;
@Autowired
public MyService(UserRepository userRepository, AddressRepository addressRepository) {
this.userRepository = userRepository;
this.addressRepository = addressRepository;
}
public boolean isUserHasAddress(String username){
// omitting the method details, will return true always
return true;
}
}
Now we need to write unit test for the above class. Here is a way to do it:
@RunWith(SpringRunner.class)
public class MyServiceTest {
private MyService myService;
@MockBean
private UserRepository userRepository;
@MockBean
private AddressRepository addressRepository;
@Before
public void setUp() throws Exception {
myService = new MyService(
userRepository,
addressRepository
);
}
@Test
public void isUserHasAddress_WhenUserNameFound_True(){
// You need to mock any call to repositories here. So if your isUserHasAddress method calls a repository method, you need to mock the behavior here
boolean isUserFound = myService.isUserHasAddress("testusername");
Assert.assertTrue(isUserFound);
}
}
We are creating the bean which we want to test i.e. myService in our case inside the @Before method. We are supplying the required dependencies to the constructor here.
Hope that helps! Happy coding!
Let's assume our service class is like the following:
@Service
class MyService {
private final UserRepository userRepository;
private final AddressRepository addressRepository;
@Autowired
public MyService(UserRepository userRepository, AddressRepository addressRepository) {
this.userRepository = userRepository;
this.addressRepository = addressRepository;
}
public boolean isUserHasAddress(String username){
// omitting the method details, will return true always
return true;
}
}
Now we need to write unit test for the above class. Here is a way to do it:
@RunWith(SpringRunner.class)
public class MyServiceTest {
private MyService myService;
@MockBean
private UserRepository userRepository;
@MockBean
private AddressRepository addressRepository;
@Before
public void setUp() throws Exception {
myService = new MyService(
userRepository,
addressRepository
);
}
@Test
public void isUserHasAddress_WhenUserNameFound_True(){
// You need to mock any call to repositories here. So if your isUserHasAddress method calls a repository method, you need to mock the behavior here
boolean isUserFound = myService.isUserHasAddress("testusername");
Assert.assertTrue(isUserFound);
}
}
Explanation
Although the above code is self-explanatory here is a brief explanation of what is going on here. The @MockBean annotation will automatically create a mock instance of the bean and inject it here. You just need to add @RunWith(SpringRunner.class) for that.We are creating the bean which we want to test i.e. myService in our case inside the @Before method. We are supplying the required dependencies to the constructor here.
Hope that helps! Happy coding!
Comments
Post a Comment