In this post, I am going to show how to unit test the business layer of the lead microservice that I am developing. A couple of things to keep in mind to write the unit test for the business layer.
- These tests run must very fast for quick feedback.
- Only the business layer is involved and hence the web layer and repository layer should not be started. In other words, the Spring web tier beans should not be created and neither any database connections should be used. (This helps to achieve #1).
- The repository layer will be mocked using Mockito.
- The fluent assert from AssertJ library will be used.
The source code of the lead business unit test is shown in listing below.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.effectiv.crm.business.ut; | |
import static org.mockito.Matchers.any; | |
import static org.mockito.Mockito.times; | |
import static org.mockito.Mockito.verify; | |
import static org.mockito.Mockito.verifyNoMoreInteractions; | |
import static org.mockito.Mockito.when; | |
import static org.assertj.core.api.Assertions.*; | |
import java.util.ArrayList; | |
import java.util.List; | |
import org.junit.Before; | |
import org.junit.Test; | |
import org.mockito.ArgumentCaptor; | |
import org.mockito.Mockito; | |
import org.springframework.data.domain.Page; | |
import org.springframework.data.domain.PageImpl; | |
import org.springframework.data.domain.PageRequest; | |
import org.springframework.data.domain.Pageable; | |
import com.effectiv.crm.business.LeadBusinessDelegate; | |
import com.effectiv.crm.domain.Lead; | |
import com.effectiv.crm.repository.LeadRepository; | |
public class LeadBusinessDelegateTest { | |
private LeadBusinessDelegate leadBusinessDelegate; | |
private LeadRepository leadRepository; | |
@Before | |
public void setUp() { | |
leadRepository = Mockito.mock(LeadRepository.class); | |
leadBusinessDelegate = new LeadBusinessDelegate(leadRepository); | |
} | |
@Test | |
public void findOne() { | |
Lead l = new Lead(); | |
l.setId("1"); | |
l.setFirstName("Virat"); | |
l.setLastName("Kohli"); | |
// mock | |
when(leadRepository.findOne(any(String.class))).thenReturn(l); | |
Lead rl = leadBusinessDelegate.findOne("1"); | |
assertThat(rl.getId()).isEqualTo("1"); | |
assertThat(rl.getFirstName()).isEqualTo("Virat"); | |
assertThat(rl.getLastName()).isEqualTo("Kohli"); | |
verify(leadRepository, times(1)).findOne("1"); | |
verifyNoMoreInteractions(leadRepository); | |
} | |
@Test | |
public void findOneDoesNotExist() { | |
// mock | |
when(leadRepository.findOne(any(String.class))).thenReturn(null); | |
Lead rl = leadBusinessDelegate.findOne("1"); | |
assertThat(rl).isNull(); | |
verify(leadRepository, times(1)).findOne("1"); | |
verifyNoMoreInteractions(leadRepository); | |
} | |
@Test | |
public void testFindAll() { | |
List<Lead> leads = new ArrayList<Lead>(); | |
Lead l = new Lead(); | |
l.setId("1"); | |
leads.add(l); | |
l = new Lead(); | |
l.setId("2"); | |
leads.add(l); | |
l = new Lead(); | |
l.setId("3"); | |
leads.add(l); | |
l = new Lead(); | |
l.setId("4"); | |
leads.add(l); | |
l = new Lead(); | |
l.setId("5"); | |
leads.add(l); | |
when(leadRepository.findAll(any(Pageable.class))).thenReturn(new PageImpl<>(leads)); | |
PageRequest p = new PageRequest(1, 5); | |
Page<Lead> rLeadPage = leadBusinessDelegate.findAll(p); | |
assertThat(rLeadPage.getTotalElements()).isEqualTo(5L); | |
assertThat(rLeadPage.getTotalPages()).isEqualTo(1); | |
List<Lead> rLeads = rLeadPage.getContent(); | |
int counter = 1; | |
for (Lead ld : rLeads) { | |
assertThat(ld.getId()).isEqualTo(counter + ""); | |
counter++; | |
} | |
verify(leadRepository, times(1)).findAll(p); | |
verifyNoMoreInteractions(leadRepository); | |
} | |
@Test | |
public void testSave() { | |
Lead lead = new Lead(); | |
lead.setAnnualRevenue(50000.00D); | |
lead.setCompany("EFFECTIV"); | |
lead.setDeleted(false); | |
lead.setDescription("Unit - test - entity :: Lead"); | |
lead.setDesignation("Project Manager"); | |
lead.setEmail("effectvlead@effectiv.com"); | |
lead.setEmailOptOut(false); | |
lead.setId("1"); | |
// mock | |
when(leadRepository.save(any(Lead.class))).thenReturn(lead); | |
Lead rLead = leadBusinessDelegate.save(lead); | |
assertThat(rLead).isNotNull(); | |
assertThat(rLead.getId()).isEqualTo("1"); //ensure that ID does not change and lead object is returned | |
verify(leadRepository, times(1)).save(lead); | |
verifyNoMoreInteractions(leadRepository); | |
} | |
@Test | |
public void testDelete() { | |
// mock | |
Lead lead = new Lead(); | |
lead.setAnnualRevenue(50000.00D); | |
lead.setCompany("EFFECTIV"); | |
lead.setDeleted(false); | |
lead.setDescription("Unit - test - entity :: Lead"); | |
lead.setDesignation("Project Manager"); | |
lead.setEmail("effectvlead@effectiv.com"); | |
lead.setEmailOptOut(false); | |
lead.setId("1"); | |
// mock | |
when(leadRepository.findOne(any(String.class))).thenReturn(lead); | |
leadBusinessDelegate.delete("1"); | |
ArgumentCaptor<Lead> leadCaptor = ArgumentCaptor.forClass(Lead.class); | |
verify(leadRepository, times(1)).findOne("1"); | |
verify(leadRepository, times(1)).save(leadCaptor.capture()); | |
verifyNoMoreInteractions(leadRepository); | |
Lead deletedLead = leadCaptor.getValue(); | |
//check same lead | |
assertThat(deletedLead.getId()).isEqualTo("1"); | |
//check if deleted flag is true | |
assertThat(deletedLead.isDeleted()).isEqualTo(true); | |
} | |
} |
I will pause the microservices test series for couple weeks. In the next post, I will write again about "12-factor app" and then introduce Spring Cloud Config Server and see how we can implement one key factor of cloud-native application. So, stay tuned.
The source code is available at - https://github.com/kdhrubo/playground/tree/develop/lead-backend
Comments
Post a Comment