springboot-testing cheetsheeet
springboot-testing cheetsheeet
---------------------
* Junit mockito intro
* Spring boot testing
* Communication bw spring boot applications
Unit testing:
where any given test covers the smallest unit of a program (a function or
procedure).
It may or may not take some input parameters and may or may not return some
values.
Integration testing:
where individual units are tested together to check whether all the
units interact with each other as expected.
@BeforeEach : To execute any logic once per test method before starting test
method.
@AfterEach : To execute any logic once per test method after finishing test
method.
@BeforeAll : To execute any logic once per test case before starting.
@AfterAll : To execute any logic once per test case after finishing.
Calculator example:
------------------
@Test
void testDivide() {
Assertions.assertThrows(ArithmeticException.class, ()-> cal.divide(3,
0));
}
@Test
void testDivide() {
int sum=Assertions.assertTimeout(Duration.ofMillis(100), ()->
cal.add(2, 1));
}
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@EnabledOnOs(OS.LINUX)
@EnabledOnJre(JRE.JAVA_15)
@DisplayName("test for add employee")
@Order(value = 1)
AssertEquals()
assertNotNull(object):
assertNull(object):
assertTrue()/assertFalse()
assertAll(Executable...)
assertThrow()
assertNotThrow()
assertTimeOut()
Demo @TestMethodOrder:
_____________________
@TestMethodOrder : We can define multiple test methods inside Testcase.
Those are executed in Random order by default.
@TestMethodOrder(OrderAnnotation.class)
public class TestEmployee {
@Order(value = 1)
@Test
public void testSave() {
System.out.println("saving");
}
Eg:
DisplayName("test for employee dao")
public class TestEmployee {
@Tag
----------
@Test
public void testSave(TestInfo info) {
System.out.println(info.getTestMethod().toString());
System.out.println("saving");
}
@Tag(value = "dev")
@Test
public void testUpdate() {
System.out.println("updating ");
}
@Tag(value = "prod")
@Test
public void testDelete() {
System.out.println("deleting");
}
}
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
<configuration>
<!-- include tags -->
<groups>prod</groups>
<!-- exclude tags -->
<excludedGroups>dev</excludedGroups>
</configuration>
</plugin>
</plugins>
</build>
@ParameterizedTest
___________________
@ParameterizedTest
@CsvFileSource(resources = "/data.csv", numLinesToSkip = 1)
void toUpperCase_ShouldGenerateTheExpectedUppercaseValueCSVFile(
String input, String expected) {
String actualValue = input.toUpperCase();
assertEquals(expected, actualValue);
}
input,expected
test,TEST
tEst,TEST
Java,JAVA
getting started:
------------------
Why mockito?
-----------
public interface BookDao {
public List<String> getBooks();
}
@Override
public List<String> getBooks(String subject) {
return bookDao.getBooks().stream().filter(title ->
title.contains(subject)).collect(Collectors.toList());
}
import org.junit.Assert;
@Test
public void getBookTest() {
BookDao dao=new BookDaoImpl();
@ExtendWith(MockitoExtension.class)
class BookServiceImplTest {
@InjectMocks
private BookServiceImpl bookServiceImpl;
@Mock
private BookDao bookDao;
@BeforeEach
void setUp() throws Exception {
List<String> allBooks=Arrays.asList("java","rich dad poor dad","java
adv");
when(bookDao.getBooks()).thenReturn(allBooks);
@AfterEach
void tearDown() throws Exception {
}
@Test
void test() {
List<String> books=bookServiceImpl.getBooks("java");
assertEquals(2, books.size());
}
MockitoAnnotations.initMocks(this) vs @RunWith(MockitoJUnitRunner.class)
Note:
----
Mockito cannot mock or spy on Java constructs such as final classes and
methods, static methods, enums, private methods, the equals() and
hashCode() methods, primitive types, and anonymous classes
Example:
--------
@Repository
public class BookDaoImpl implements BookDao {
@Override
public List<String> getBooks() {
log();
return null;
}
@RunWith(MockitoJUnitRunner.class)
public class DemoTest {
@Spy
BookDaoImpl dao;
@InjectMocks
BookServiceImpl bookService;
application.properties
---------------------
server.port=8080
spring.h2.console.enabled=true
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=foo
spring.datasource.password=foo
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=update
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.annotation.Rollback;
import java.util.List;
import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
@DataJpaTest
class ProductRepoTest {
@Autowired
private ProductRepo productRepo;
@BeforeEach
void setUp() {
product=new Product("laptop", 120000);
}
@Test
@Rollback(value = true)
public void givenProductObjectWhenSaveReturnProductObject(){
Product productSaved=productRepo.save(product);
assertThat(productSaved).isNotNull();
assertThat(productSaved.getId()).isGreaterThan(0);
}
@DisplayName("JUnit test for get all employees operation")
@Test
public void givenProductList_whenFindAll_thenProductList(){
//given
Product p1=new Product("laptop",120000);
Product p2=new Product("laptop cover",1200);
productRepo.save(p1);
productRepo.save(p2);
// when - action or the behaviour that we are going test
List<Product> productList=productRepo.findAll();
// then - verify the output
assertThat(productList).isNotNull();
assertThat(productList.size()).isEqualTo(2);
}
@DisplayName("JUnit test for get product by id operation")
@Test
public void givenProductObject_whenFindById_thenReturnProductObject(){
// given - precondition or setup
Product p1=new Product("laptop",120000);
productRepo.save(p1);
assertThat(updatedProduct.getPrice()).isEqualTo(130000);
}
@AfterEach
void tearDown() {
}
}
import com.productapp.repo.Product;
import com.productapp.repo.ProductRepo;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.Collections;
import java.util.List;
@ExtendWith(MockitoExtension.class)
class ProductServiceImplTest {
@Mock
private ProductRepo productRepo;
@InjectMocks
private ProductServiceImpl productService;
@BeforeEach
void setUp() {
product=new Product("laptop", 120000);
}
given(productRepo.findAll()).willReturn(List.of(product,product2));
@AfterEach
void tearDown() {
}
}
import com.fasterxml.jackson.databind.ObjectMapper;
import com.productapp.repo.Product;
import com.productapp.service.ProductService;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import java.util.ArrayList;
import java.util.List;
@Autowired
private MockMvc mockMvc;
@MockBean
private ProductService productService;
@Autowired
private ObjectMapper objectMapper;
@Test
public void givenProductObject_whenCreateProduct_thenReturnSavedProduct()
throws Exception{
// @Test
public void givenInvalidProductId_whenGetProductById_thenReturnEmpty() throws
Exception{
// given - precondition or setup
int productId = 1;
Product product=new Product(1,"laptop", 120000);
given(productService.getById(productId)).willReturn(null);
@AfterEach
void tearDown() {
}
}
integration testing:
-------------------
import com.fasterxml.jackson.databind.ObjectMapper;
import com.productapp.repo.Product;
import com.productapp.repo.ProductRepo;
import com.productapp.service.ProductService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import java.util.ArrayList;
import java.util.List;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
@Autowired
private ProductService productService;
@Autowired
private ProductRepo productRepo;
@Autowired
private ObjectMapper objectMapper;
@BeforeEach
void setup(){
productRepo.deleteAll();
}
@Test
public void givenProductObject_whenCreateProduct_thenReturnSavedProduct()
throws Exception{
@Test
public void givenListOfProducts_whenGetAllProducts_thenReturnProductList()
throws Exception{
// given - precondition or setup
List<Product> listOfProducts = new ArrayList<>();
listOfProducts.add(Product.builder().name("foo").price(7000).build());
listOfProducts.add(Product.builder().name("bar").price(7000).build());
productRepo.saveAll(listOfProducts);
// when - action or the behaviour that we are going test
ResultActions response = mockMvc.perform(get("/products"));
JaCoCo
--------
https://medium.com/@truongbui95/jacoco-code-coverage-with-spring-boot-835af8debc68
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.version}</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<configuration>
<excludes>
<!-- com.productapp.Productapp01Application
com.productapp.exceptions.ProductNotFoundException
com.productapp.dto.ErrorInfo
com.productapp.repo.Product
-->
<exclude>com/productapp/Productapp01Application.class</exclude>
<exclude>com/productapp/exceptions/ProductNotFoundException.class</exclude>
<exclude>com/productapp/dto/ErrorInfo.class</exclude>
<exclude>com/productapp/repo/Product.class</exclude>
</excludes>
</configuration>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>jacoco-check</id>
<goals>
<goal>check</goal>
</goals>
<configuration>
<rules>
<rule>
<element>PACKAGE</element>
<limits>
<limit>
<counter>LINE</counter>
<value>COVEREDRATIO</value>
<minimum>00%</minimum>
</limit>
</limits>
</rule>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
SonarCube
------------
https://blog.stackademic.com/integratation-of-sonarqube-with-springboot-
6d2cebd4ef95
port : 9000