JAVA-84: Moved 1 article to spring-boot-testing

This commit is contained in:
sampadawagde
2020-08-28 17:57:38 +05:30
parent e1a1af012e
commit f04d73e8fd
27 changed files with 70 additions and 544 deletions

View File

@@ -14,3 +14,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
- [Embedded Redis Server with Spring Boot Test](https://www.baeldung.com/spring-embedded-redis)
- [Testing Spring Boot @ConfigurationProperties](https://www.baeldung.com/spring-boot-testing-configurationproperties)
- [Prevent ApplicationRunner or CommandLineRunner Beans From Executing During Junit Testing](https://www.baeldung.com/spring-junit-prevent-runner-beans-testing-execution)
- [Testing in Spring Boot](https://www.baeldung.com/spring-boot-testing)

View File

@@ -34,6 +34,14 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>

View File

@@ -0,0 +1,46 @@
package com.baeldung.boot.testing;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.Size;
import java.util.Date;
@Entity
@Table(name = "person")
public class Employee {
public Employee() {
}
public Employee(String name) {
this.name = name;
}
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Size(min = 3, max = 20)
private String name;
private Date birthday;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@@ -0,0 +1,17 @@
package com.baeldung.boot.testing;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
@Repository
@Transactional
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
public Employee findByName(String name);
public List<Employee> findAll();
}

View File

@@ -0,0 +1,33 @@
package com.baeldung.boot.testing;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api")
public class EmployeeRestController {
@Autowired
private EmployeeService employeeService;
@PostMapping("/employees")
public ResponseEntity<Employee> createEmployee(@RequestBody Employee employee) {
HttpStatus status = HttpStatus.CREATED;
Employee saved = employeeService.save(employee);
return new ResponseEntity<>(saved, status);
}
@GetMapping("/employees")
public List<Employee> getAllEmployees() {
return employeeService.getAllEmployees();
}
}

View File

@@ -0,0 +1,16 @@
package com.baeldung.boot.testing;
import java.util.List;
public interface EmployeeService {
public Employee getEmployeeById(Long id);
public Employee getEmployeeByName(String name);
public List<Employee> getAllEmployees();
public boolean exists(String email);
public Employee save(Employee employee);
}

View File

@@ -0,0 +1,43 @@
package com.baeldung.boot.testing;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional
public class EmployeeServiceImpl implements EmployeeService {
@Autowired
private EmployeeRepository employeeRepository;
@Override
public Employee getEmployeeById(Long id) {
return employeeRepository.findById(id).orElse(null);
}
@Override
public Employee getEmployeeByName(String name) {
return employeeRepository.findByName(name);
}
@Override
public boolean exists(String name) {
if (employeeRepository.findByName(name) != null) {
return true;
}
return false;
}
@Override
public Employee save(Employee employee) {
return employeeRepository.save(employee);
}
@Override
public List<Employee> getAllEmployees() {
return employeeRepository.findAll();
}
}

View File

@@ -4,4 +4,6 @@ spring.redis.port= 6379
# security
spring.security.user.name=john
spring.security.user.password=123
spring.security.user.password=123
spring.main.allow-bean-definition-overriding=true

View File

@@ -0,0 +1,8 @@
jdbc.driverClassName=org.h2.Driver
jdbc.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
jdbc.user=sa
jdbc.pass=sa
hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.show_sql=true
hibernate.hbm2ddl.auto=create-drop

View File

@@ -0,0 +1,73 @@
package com.baeldung.boot.testing;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.hasSize;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.util.Arrays;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.mockito.internal.verification.VerificationModeFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
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.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import com.baeldung.boot.testing.Employee;
import com.baeldung.boot.testing.EmployeeRestController;
import com.baeldung.boot.testing.EmployeeService;
@RunWith(SpringRunner.class)
@WebMvcTest(value = EmployeeRestController.class, excludeAutoConfiguration = SecurityAutoConfiguration.class)
public class EmployeeControllerIntegrationTest {
@Autowired
private MockMvc mvc;
@MockBean
private EmployeeService service;
@Before
public void setUp() throws Exception {
}
@Test
public void whenPostEmployee_thenCreateEmployee() throws Exception {
Employee alex = new Employee("alex");
given(service.save(Mockito.any())).willReturn(alex);
mvc.perform(post("/api/employees").contentType(MediaType.APPLICATION_JSON).content(JsonUtil.toJson(alex))).andExpect(status().isCreated()).andExpect(jsonPath("$.name", is("alex")));
verify(service, VerificationModeFactory.times(1)).save(Mockito.any());
reset(service);
}
@Test
public void givenEmployees_whenGetEmployees_thenReturnJsonArray() throws Exception {
Employee alex = new Employee("alex");
Employee john = new Employee("john");
Employee bob = new Employee("bob");
List<Employee> allEmployees = Arrays.asList(alex, john, bob);
given(service.getAllEmployees()).willReturn(allEmployees);
mvc.perform(get("/api/employees").contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()).andExpect(jsonPath("$", hasSize(3))).andExpect(jsonPath("$[0].name", is(alex.getName()))).andExpect(jsonPath("$[1].name", is(john.getName())))
.andExpect(jsonPath("$[2].name", is(bob.getName())));
verify(service, VerificationModeFactory.times(1)).getAllEmployees();
reset(service);
}
}

View File

@@ -0,0 +1,72 @@
package com.baeldung.boot.testing;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
import org.springframework.test.context.junit4.SpringRunner;
import com.baeldung.boot.testing.Employee;
import com.baeldung.boot.testing.EmployeeRepository;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@DataJpaTest
public class EmployeeRepositoryIntegrationTest {
@Autowired
private TestEntityManager entityManager;
@Autowired
private EmployeeRepository employeeRepository;
@Test
public void whenFindByName_thenReturnEmployee() {
Employee alex = new Employee("alex");
entityManager.persistAndFlush(alex);
Employee found = employeeRepository.findByName(alex.getName());
assertThat(found.getName()).isEqualTo(alex.getName());
}
@Test
public void whenInvalidName_thenReturnNull() {
Employee fromDb = employeeRepository.findByName("doesNotExist");
assertThat(fromDb).isNull();
}
@Test
public void whenFindById_thenReturnEmployee() {
Employee emp = new Employee("test");
entityManager.persistAndFlush(emp);
Employee fromDb = employeeRepository.findById(emp.getId()).orElse(null);
assertThat(fromDb.getName()).isEqualTo(emp.getName());
}
@Test
public void whenInvalidId_thenReturnNull() {
Employee fromDb = employeeRepository.findById(-11l).orElse(null);
assertThat(fromDb).isNull();
}
@Test
public void givenSetOfEmployees_whenFindAll_thenReturnAllEmployees() {
Employee alex = new Employee("alex");
Employee ron = new Employee("ron");
Employee bob = new Employee("bob");
entityManager.persist(alex);
entityManager.persist(bob);
entityManager.persist(ron);
entityManager.flush();
List<Employee> allEmployees = employeeRepository.findAll();
assertThat(allEmployees).hasSize(3).extracting(Employee::getName).containsOnly(alex.getName(), ron.getName(), bob.getName());
}
}

View File

@@ -0,0 +1,86 @@
package com.baeldung.boot.testing;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.hasSize;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.io.IOException;
import java.util.List;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import com.baeldung.boot.Application;
import com.baeldung.boot.testing.Employee;
import com.baeldung.boot.testing.EmployeeRepository;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = Application.class)
@AutoConfigureMockMvc
@EnableAutoConfiguration(exclude=SecurityAutoConfiguration.class)
// @TestPropertySource(locations = "classpath:application-integrationtest.properties")
@AutoConfigureTestDatabase
public class EmployeeRestControllerIntegrationTest {
@Autowired
private MockMvc mvc;
@Autowired
private EmployeeRepository repository;
@After
public void resetDb() {
repository.deleteAll();
}
@Test
public void whenValidInput_thenCreateEmployee() throws IOException, Exception {
Employee bob = new Employee("bob");
mvc.perform(post("/api/employees").contentType(MediaType.APPLICATION_JSON).content(JsonUtil.toJson(bob)));
List<Employee> found = repository.findAll();
assertThat(found).extracting(Employee::getName).containsOnly("bob");
}
@Test
public void givenEmployees_whenGetEmployees_thenStatus200() throws Exception {
createTestEmployee("bob");
createTestEmployee("alex");
// @formatter:off
mvc.perform(get("/api/employees").contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$", hasSize(greaterThanOrEqualTo(2))))
.andExpect(jsonPath("$[0].name", is("bob")))
.andExpect(jsonPath("$[1].name", is("alex")));
// @formatter:on
}
//
private void createTestEmployee(String name) {
Employee emp = new Employee(name);
repository.saveAndFlush(emp);
}
}

View File

@@ -0,0 +1,132 @@
package com.baeldung.boot.testing;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.mockito.internal.verification.VerificationModeFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Bean;
import org.springframework.test.context.junit4.SpringRunner;
import com.baeldung.boot.testing.Employee;
import com.baeldung.boot.testing.EmployeeRepository;
import com.baeldung.boot.testing.EmployeeService;
import com.baeldung.boot.testing.EmployeeServiceImpl;
@RunWith(SpringRunner.class)
public class EmployeeServiceImplIntegrationTest {
@TestConfiguration
static class EmployeeServiceImplTestContextConfiguration {
@Bean
public EmployeeService employeeService() {
return new EmployeeServiceImpl();
}
}
@Autowired
private EmployeeService employeeService;
@MockBean
private EmployeeRepository employeeRepository;
@Before
public void setUp() {
Employee john = new Employee("john");
john.setId(11L);
Employee bob = new Employee("bob");
Employee alex = new Employee("alex");
List<Employee> allEmployees = Arrays.asList(john, bob, alex);
Mockito.when(employeeRepository.findByName(john.getName())).thenReturn(john);
Mockito.when(employeeRepository.findByName(alex.getName())).thenReturn(alex);
Mockito.when(employeeRepository.findByName("wrong_name")).thenReturn(null);
Mockito.when(employeeRepository.findById(john.getId())).thenReturn(Optional.of(john));
Mockito.when(employeeRepository.findAll()).thenReturn(allEmployees);
Mockito.when(employeeRepository.findById(-99L)).thenReturn(Optional.empty());
}
@Test
public void whenValidName_thenEmployeeShouldBeFound() {
String name = "alex";
Employee found = employeeService.getEmployeeByName(name);
assertThat(found.getName()).isEqualTo(name);
}
@Test
public void whenInValidName_thenEmployeeShouldNotBeFound() {
Employee fromDb = employeeService.getEmployeeByName("wrong_name");
assertThat(fromDb).isNull();
verifyFindByNameIsCalledOnce("wrong_name");
}
@Test
public void whenValidName_thenEmployeeShouldExist() {
boolean doesEmployeeExist = employeeService.exists("john");
assertThat(doesEmployeeExist).isEqualTo(true);
verifyFindByNameIsCalledOnce("john");
}
@Test
public void whenNonExistingName_thenEmployeeShouldNotExist() {
boolean doesEmployeeExist = employeeService.exists("some_name");
assertThat(doesEmployeeExist).isEqualTo(false);
verifyFindByNameIsCalledOnce("some_name");
}
@Test
public void whenValidId_thenEmployeeShouldBeFound() {
Employee fromDb = employeeService.getEmployeeById(11L);
assertThat(fromDb.getName()).isEqualTo("john");
verifyFindByIdIsCalledOnce();
}
@Test
public void whenInValidId_thenEmployeeShouldNotBeFound() {
Employee fromDb = employeeService.getEmployeeById(-99L);
verifyFindByIdIsCalledOnce();
assertThat(fromDb).isNull();
}
@Test
public void given3Employees_whengetAll_thenReturn3Records() {
Employee alex = new Employee("alex");
Employee john = new Employee("john");
Employee bob = new Employee("bob");
List<Employee> allEmployees = employeeService.getAllEmployees();
verifyFindAllEmployeesIsCalledOnce();
assertThat(allEmployees).hasSize(3).extracting(Employee::getName).contains(alex.getName(), john.getName(), bob.getName());
}
private void verifyFindByNameIsCalledOnce(String name) {
Mockito.verify(employeeRepository, VerificationModeFactory.times(1)).findByName(name);
Mockito.reset(employeeRepository);
}
private void verifyFindByIdIsCalledOnce() {
Mockito.verify(employeeRepository, VerificationModeFactory.times(1)).findById(Mockito.anyLong());
Mockito.reset(employeeRepository);
}
private void verifyFindAllEmployeesIsCalledOnce() {
Mockito.verify(employeeRepository, VerificationModeFactory.times(1)).findAll();
Mockito.reset(employeeRepository);
}
}

View File

@@ -0,0 +1,14 @@
package com.baeldung.boot.testing;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
class JsonUtil {
static byte[] toJson(Object object) throws IOException {
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
return mapper.writeValueAsBytes(object);
}
}

View File

@@ -0,0 +1,4 @@
spring.datasource.url=jdbc:mysql://localhost:3306/employee_int_test
spring.datasource.username=root
spring.datasource.password=root

View File

@@ -3,4 +3,6 @@ spring.redis.host= localhost
spring.redis.port= 6370
# security
spring.security.user.name=john
spring.security.user.password=123
spring.security.user.password=123
spring.main.allow-bean-definition-overriding=true