Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Unit Testing Testing with Spring Boot SoftUni Team Technical Trainers Software University http://softuni.bg Table of Contents 1. Unit Testing Repository Layer Entities (Recap) Repositories Service Layer Web Layer Controllers 2 Have a Question? sli.do #JavaWeb 3 Unit Testing 4 What are Unit Tests? individual units of source code are tested to determine whether they are work as intended. Test System Test Modules Test Methods System Testing Integration Testing Unit Testing 5 Why to Test? More reliable code – due to less bugs Faster development – no need to constantly debug Better maintenance – because of a constant code care Clearer code – code modularity is required to write tests Cheaper – bugs in production cost more 6 Cost in Different Phases 7 Spring Unit Testing JUnit — The de-facto standard for unit testing Java applications. Spring Test & Spring Boot Test — Utilities and integration test support for Spring Boot applications. AssertJ — A fluent assertion library. Hamcrest — A library of matcher objects (also known as constraints or predicates). Mockito — A Java mocking framework. JSONassert — An assertion library for JSON. JsonPath — XPath for JSON. pom.xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> 8 Entity Testing 9 Problem 1 User.java @Entity public abstract class User implements UserDetails { public void addRole(Role role){ this.getAuthorities().add(role); } How to test? } 10 Entity Test (1) UserTest.java @RunWith(SpringRunner.class) public class UserTest { Spring Boot Test Utilities private User user; @Mock private Role role; @Before public void setUp() throws Exception { //Arrange this.user = new BasicUser(); when(this.role.getAuthority()).thenReturn("ROLE_USER"); } … } 11 Entity Test (2) UserTest.java @RunWith(SpringRunner.class) public class UserTest { @Test public void addRoleWhenRoleExists_ShouldAddRole() throws Exception { //Act this.user.addRole(this.role); //Assert Role role = this.user.getAuthorities().iterator().next(); assertEquals(role.getAuthority(), "ROLE_USER"); } } 12 Repository Testing 13 Problem 2 BikeRepository.java @Repository public interface BikeRepository extends JpaRepository<Bike, Long> { @Query(value = "SELECT b FROM Bike AS b") List<Bike> findAll(); How to test? } 14 Repository Test Spring Boot Test Utilities BikeRepositoryTest.java JPA Test @RunWith(SpringRunner.class) @DataJpaTest @AutoConfigureTestDatabase(replace = NONE) public class BikeRepositoryTest { Use Standard Database @Autowired private TestEntityManager testEntityManager; @Autowired private BikeRepository bikeRepository; Repository Alternative @Test public void findAllShouldReturnCorrectSizeList() throws Exception { int listSize = 5; for (int i = 0; i < listSize; i++) { this.testEntityManager.persist(new Bike()); } List<Bike> bikes = this.bikeRepository.findAll(); assertEquals(listSize,bikes.size()); } } 15 Repository Test Database BikeRepositoryTest.java @RunWith(SpringRunner.class) @DataJpaTest @AutoConfigureTestDatabase(replace = NONE) public class BikeRepositoryTest { @Autowired private TestEntityManager testEntityManager; } Test in in-memory database Should we test in production database? MySQL HSQL 16 In-Memory Databases (1) application.properties spring.profiles.active=dev application-dev.properties #Dev Data Source Properties spring.datasource.driverClassName=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/social_de mo?useSSL=false&createDatabaseIfNotExist=true spring.datasource.username=root spring.datasource.password=1234 17 In-Memory Databases (2) application-test.properties spring.jpa.hibernate.ddl-auto=create-drop spring.jpa.database=HSQL spring.jpa.properties.hibernate.dialect=org.hibernate.diale ct.HSQLDialect spring.datasource.driverClassName=org.hsqldb.jdbcDriver spring.datasource.url=jdbc:hsqldb:mem:social spring.datasource.username=sa spring.datasource.password= 18 In-Memory Databases (3) pom.xml <dependency> <groupId>org.hsqldb</groupId> <artifactId>hsqldb</artifactId> <scope>test</scope> </dependency> 19 In-Memory Databases (4) BikeRepositoryTest.java @RunWith(SpringRunner.class) @DataJpaTest Test Profile @ActiveProfiles("test") public class BikeRepositoryTest { @Autowired private TestEntityManager testEntityManager; } 20 Exercise: Test User and Bike Repository 21 Service Testing 22 Problem 3 BikeService.java public interface BikeService { BikeViewModel findById(long id); List<BikeViewModel> findAll(); How to test? Page<BikeViewModel> findAll(Pageable pageable); } 23 Service Testing (1) BikeService.java @RunWith(SpringRunner.class) @SpringBootTest @ActiveProfiles("test") public class BikeServiceTest { Inject in Service @Autowired private ModelMapper modelMapper; @MockBean private BikeRepository bikeRepository; @Autowired private BikeService bikeService; Mock a Bean Autowire Service 24 Service Testing (2) BikeService.java @Before public void setUp() throws Exception { Bike bike = new Bike(); bike.setId(1); bike.setModel("BMX"); when(bikeRepository.findOne(1L)).thenReturn(bike); } @Test public void wheUserIdIsProvided_ShouldReturnCorrectModel() throws Exception { BikeViewModel bikeViewModel = this.bikeService.findById(1); assertEquals(bikeViewModel.getModel(),"BMX"); } } 25 Exercise: SocialUser Service 26 Web Layer Testing 27 Problem 4 BikeService.java @GetMapping("/bikes/show/{id}") public String showBike(Model model, @PathVariable long id){ BikeViewModel bikeViewModel = this.bikeService.findById(id); model.addAttribute("bike", bikeViewModel); How to test? return "bike-show"; } 28 Disable Security for Tests application-test.properties … security.basic.enabled=false Disable Security? 29 Controller Testing (1) BikeControllerTest.java @RunWith(SpringRunner.class) @WebMvcTest(BikeController.class) @ActiveProfiles("test") @EnableSpringDataWebSupport public class BikeControllerTest { Controller Test Pagination Support (Optional) @Autowired private MockMvc mvc; @MockBean private BikeService bikeService; @Before public void setUp() throws Exception { BikeViewModel bike = new BikeViewModel(); bike.setId(1); bike.setModel("BMX"); when(bikeService.findById(1)).thenReturn(bike); } 30 Controller Testing (2) BikeControllerTest.java @Test public void showBikeWhenBikeExists_ShouldReturnViewAndModel() throws Exception { this.mvc.perform( get("/bikes/show/1")) .andExpect(status().isOk()) .andExpect(view().name("bike-show")) .andExpect(model().attribute("bike", hasProperty("id", is(1L)))) .andExpect(model().attribute("bike", hasProperty("model", is("BMX")))) .andExpect(model().attribute("bike", hasProperty("gears", is(24)))); } HTTP Status View Test Model Test 31 Controller Testing Exception Handling BikeControllerTest.java @Test public void showBikeWhenBikeNotExists_ShouldReturnNotFound() throws Exception { this.mvc.perform(get("/bikes/show/2")) .andExpect(status().is4xxClientError()) .andExpect(view().name("exceptions/bike-not-found")); } } HTTP Status View Test 32 Summary Unit Testing – critical part of the development process that ensures our application works as expected 33 Web Development Basics – Course Overview ? https://softuni.bg/courses/ License This course (slides, examples, demos, videos, homework, etc.) is licensed under the "Creative Commons AttributionNonCommercial-ShareAlike 4.0 International" license 35 Free Trainings @ Software University Software University Foundation – softuni.org Software University – High-Quality Education, Profession and Job for Software Developers softuni.bg Software University @ Facebook facebook.com/SoftwareUniversity Software University @ YouTube youtube.com/SoftwareUniversity Software University Forums – forum.softuni.bg