In previous chapter we learn how to write test cases for Controllers. So, after writing Controller Test Case, below scenario will happen.
– Controller test case fails as no controller implementation available
– So, we will write the controller code such that minimum test case passes.
– Controller needs Service class also. Since Service class is not yet written, write the Service layer.
So, in TDD, we will follow below steps: -
-- Before writing Service Class write the Test Case class. To do so, we will use Annotations:
@Mock
@InjectMock
Web Layer
(CustomerController)
Service Layer
(CustomerServiceImpl)
CustomerRepository
(Not implemented Yet)
As shown above Repository Layer is also not yet ready but we can proceed as below:
1. We can write and test our Service layer code without wiring in our complete persistence layer.
2. To complete this, we can practice the mocking provision provided by Spring Boot Test.
@Mock
CustomerRepository customerRepo;
@InjectMocks
private CustomerServiceImpl custService = new CustomerServiceImpl ();
@mock annotation on any object will enable you to set its behavior.
@InjectMocks creates an instance of the class and injects the mocks that are created with the @Mock (or @Spy) annotations into this instance.
Test case class for CustomerService : Mock all objects needed: -
@RunWith(SpringJUnit4ClassRunner.class)
@AutoConfigureMockMvc
@SpringBootTest
public class TestCustomerService {
@MockCustomerRepository customerRepo;@MockPhoneSequence phSequence;@MockPhoneSequenceRepository phRepo;@MockExtUtil util;//Injects all mocks to CustomerServiceImp@InjectMocksCustomerServiceImpl custService;//Other Pojos neededstatic CustomerDTO custDTO;static Customer cust;
//Setting Exception Rule@Rulepublic ExpectedException expectedException = ExpectedException.none();Test case class for CustomerService :Set up the fixtures: -@BeforeClasspublic static void initialise() {
custDTO = new CustomerDTO();cust = new Customer();
}
@Beforepublic void init() {
MockitoAnnotations.initMocks(this);custDTO.setSsnId("123456789010");custDTO.setAddress("#25, Millers Road, Bangalore");custDTO.setDob("1981-03-20");custDTO.setEmailId("Robert_Smith@gmail.com");custDTO.setFirstName("Robert");custDTO.setLastName("Smith");
}
@Afterpublic void tearDown() {
customerRepo.deleteAll();phRepo.deleteAll();
}
}
Testing updateCustomer() method of CustomerService class [Positive test case]: -
@Test
public void testUpdateCustomerPositive() throws CustomerException {
cust = CustomerDTO.prepareEntity(custDTO);cust.setPhoneNo("9876536750");custDTO.setPhoneNo("9876536750");custDTO.setAddress("Jubilee Hills, Hyderabad");//Training the mock objectsMockito.when(customerRepo.saveAndFlush(cust)).thenReturn(cust);Mockito.when(customerRepo.findByPhoneNo(Mockito.eq("9876536750"))).thenReturn(cust);//Making the actual callcustService.updateCustomer("9876536750", "JubileeHills, Hyderabad");//Verifying if the calls were made or notMockito.verify(customerRepo).findByPhoneNo(Mockito.eq("9876536750"));
try {
Mockito.verify(customerRepo).saveAndFlush(Mockito.any(Customer.class));
} catch (AssertionError e) {}
}
Testing updateCustomer() method of CustomerService class [Negative test case]: -
@Test(expected = CustomerException.class)
public void testUpdateCustomerInvalidPhoneNo() throws CustomerException {
cust = CustomerDTO.prepareEntity(custDTO);cust.setPhoneNo("9876536750");custDTO.setPhoneNo("9876536750");//Setting the mock objects behaviourMockito.when(customerRepo.saveAndFlush(cust)).thenReturn(cust);Mockito.when(customerRepo.findByPhoneNo(Mockito.eq("9876536751"))).thenReturn(null);//Calling Service method to update customercustService.updateCustomer("9876536751", "JubileeHills, Hyderabad");//Verifying if the methods were called by customerserviceMockito.verify(customerRepo).findByPhoneNo(Mockito.eq("9876536751"));expectedException.expect(InfyTelException.class);expectedException.expectMessage(ExceptionConstants.CUSTOMER_NOT_FOUND.toString());
try {
Mockito.verify(customerRepo).saveAndFlush(Mockito.any(Customer.class));
} catch (AssertionError e) {}
}
Note: Similarly test methods for other functionalities have to be written