今天整理了下,springboot下单元测试基本用法
若使用了 @RunWith(SpringRunner.class)配置,需要用 org.junit.Test运行,juint4包, junit5包org.junit.jupiter.api.Test 不需要RunWith注解.
一 引入依赖
1 <parent>
2 <groupId>org.springframework.boot</groupId>
3 <artifactId>spring-boot-starter-parent</artifactId>
4 <version>2.3.0.RELEASE</version>
5 <relativePath/> <!-- lookup parent from repository -->
6 </parent>
7 <groupId>com.example</groupId>
8 <artifactId>mvctest</artifactId>
9 <version>0.0.1-SNAPSHOT</version>
10 <name>mvctest</name>
11 <description>Demo project for Spring Boot</description>
12
13 <properties>
14 <java.version>1.8</java.version>
15 </properties>
16
17 <dependencies>
18 <dependency>
19 <groupId>org.springframework.boot</groupId>
20 <artifactId>spring-boot-starter-web</artifactId>
21 </dependency>
22
23 <dependency>
24 <groupId>com.h2database</groupId>
25 <artifactId>h2</artifactId>
26 <scope>runtime</scope>
27 </dependency>
28 <dependency>
29 <groupId>org.springframework.boot</groupId>
30 <artifactId>spring-boot-starter-data-jpa</artifactId>
31 </dependency>
32 <dependency>
33 <groupId>org.projectlombok</groupId>
34 <artifactId>lombok</artifactId>
35 <optional>true</optional>
36 </dependency>
37 <dependency>
38 <groupId>org.springframework.boot</groupId>
39 <artifactId>spring-boot-starter-test</artifactId>
40 <scope>test</scope>
41 <exclusions>
42 <exclusion>
43 <groupId>org.junit.vintage</groupId>
44 <artifactId>junit-vintage-engine</artifactId>
45 </exclusion>
46 </exclusions>
47 </dependency>
48 <dependency>
49 <groupId>junit</groupId>
50 <artifactId>junit</artifactId>
51 <scope>test</scope>
52 </dependency>
53 </dependencies>
54
55 <build>
56 <plugins>
57 <plugin>
58 <groupId>org.springframework.boot</groupId>
59 <artifactId>spring-boot-maven-plugin</artifactId>
60 </plugin>
61 </plugins>
62 </build>
二 接口代码
package com.example.mvctest.controller;
import com.example.mvctest.dao.User;
import com.example.mvctest.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
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.RestController;
import java.util.List;
/**
* @Description TODO
* @Author Administrator
* @Email wangrqsh@163.com
* @Date 2020/6/6 0006 下午 23:28
* @Version 1.0
*/
@RestController
public class UserController {
@Autowired
UserService userService;
@GetMapping("/userList")
public List<User> getUserList(){
return userService.findAll();
}
@GetMapping("/user")
public User getUser(Long id){
return userService.findById(id);
}
@PostMapping("/user")
public User postUser(@RequestBody User user){
return userService.save(user);
}
}
package com.example.mvctest.service;
import com.example.mvctest.dao.User;
import com.example.mvctest.dao.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @Description TODO
* @Date 2020/6/7 0007 上午 11:04
* @Version 1.0
*/
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepository;
@Override
public User findByName(String name) {
return userRepository.findByName(name);
}
@Override
public User findById(Long id) {
return userRepository.findById(id).get();
}
@Override
public User save(User user) {
return userRepository.save(user);
}
@Override
public List<User> findAll() {
return (List<User> )userRepository.findAll();
}
}
@Setter
@Getter
@ToString
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private Integer age;
private String address;
public User() {
}
public User(String name, Integer age, String address) {
this.name = name;
this.age = age;
this.address = address;
}
public User(Long id,String name, Integer age, String address) {
this.id = id;
this.name = name;
this.age = age;
this.address = address;
}
}
@Repository
public interface UserRepository extends PagingAndSortingRepository<User,Long> {
User findByName(String name);
}
二 dao单层测试
package com.example.mvctest.autoconfigtest;
import com.example.mvctest.dao.User;
import com.example.mvctest.dao.UserRepository;
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.boot.test.autoconfigure.orm.jpa.TestEntityManager;
import static org.assertj.core.api.Assertions.assertThat;
@DataJpaTest
public class AutoConfigureDataJpaTest {
@Autowired
private TestEntityManager entityManager;
@Autowired
private UserRepository userRepository;
@Test
public void dao_user_test(){
User user = new User("leo",5,"合肥");
entityManager.persist(user);
entityManager.flush();
User byName = userRepository.findByName(user.getName());
assertThat(byName.getName()).isEqualTo(user.getName());
}
}
三 service单层测试
package com.example.mvctest.autoconfigtest;
import com.example.mvctest.dao.User;
import com.example.mvctest.dao.UserRepository;
import com.example.mvctest.service.UserService;
import com.example.mvctest.service.UserServiceImpl;
import org.assertj.core.api.Assertions;
import org.junit.Test;
import org.junit.runner.RunWith;
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 java.util.Optional;
import static org.mockito.Mockito.when;
@RunWith(SpringRunner.class)
public class ServiceLayerTest {
@TestConfiguration
static class ServiceTestConfiguer{
@Bean
public UserService userService(){
return new UserServiceImpl();
}
}
@Autowired
UserService userService;
@MockBean
UserRepository userRepository;
@Test
public void user_service_mock_dao_test(){
User user = new User(1L,"tim",3,"hubei");
when(userRepository.findById(user.getId())).thenReturn(Optional.of(user));
Assertions.assertThat(userService.findById(1L).getId()).isEqualTo(1L);
}
}
四 controller单层测试
package com.example.mvctest.autoconfigtest;
import com.example.mvctest.controller.UserController;
import com.example.mvctest.dao.User;
import com.example.mvctest.service.UserService;
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 java.util.ArrayList;
import java.util.List;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.mockito.BDDMockito.given;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* @Description @WebMvcTest注解:只扫描有限类型的bead来测试,只测试控制层的逻辑,service层数据通过 mock处理,
* (limit scanned beans to @Controller, @ControllerAdvice, @JsonComponent, Filter, WebMvcConfigurer and HandlerMethodArgumentResolver.
* Regular @Component beans will not be scanned when using this annotation)
* @Date 2020/6/7 0007 下午 15:57
* @Version 1.0
*/
@WebMvcTest(UserController.class)
public class AutoConfigureMvcTest {
@Autowired
private MockMvc mvc;
@MockBean
UserService userService;
@Test
public void mvc_user_test() throws Exception {
List<User> userList = new ArrayList<>(2);
userList.add(new User(1L,"john",3,"beijing"));
userList.add(new User(2L,"jay",4,"shanghai"));
given(userService.findAll()).willReturn(userList);
this.mvc.perform(get("/userList").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(print())
.andExpect(jsonPath("$",hasSize(2)))
.andExpect(jsonPath("$[0].id",is(1)));
}
}
五 mvc接口测试
package com.example.mvctest.autoconfigtest;
import com.example.mvctest.MyApplication;
import com.example.mvctest.dao.User;
import com.example.mvctest.service.UserService;
import org.hamcrest.CoreMatchers;
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.context.TestPropertySource;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
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;
@SpringBootTest(
webEnvironment = SpringBootTest.WebEnvironment.MOCK,
classes = MyApplication.class)
@AutoConfigureMockMvc
@TestPropertySource(locations = "classpath:application-integrationtest.properties")
public class ApplicationTest {
@Autowired
private MockMvc mockMvc;
@Autowired
UserService userService;
@Test
public void web_user_get_test() throws Exception{
createTestUser();
this.mockMvc.perform(get("/user?id=1").contentType(MediaType.APPLICATION_JSON)).andDo(print())
.andExpect(status().isOk())
.andExpect(content()
.contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$.id", CoreMatchers.is(1)));
}
void createTestUser(){
User user =new User();
user.setId(1L);
userService.save(user);
}
}
六 json 格式测试
package com.example.mvctest.autoconfigtest;
import com.example.mvctest.dao.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.json.JsonTest;
import org.springframework.boot.test.json.JacksonTester;
import static org.assertj.core.api.Assertions.assertThat;
@JsonTest
public class AutoConfigureJsonTest {
@Autowired
private JacksonTester<User> json;
@Test
public void testSerialize() throws Exception {
User details = new User("Honda",8, "Civic");
// Or use JSON path based assertions
assertThat(this.json.write(details))
.hasJsonPathStringValue("@.name");
assertThat(this.json.write(details))
.extractingJsonPathStringValue("@.name")
.isEqualTo("Honda");
// Assert against a `.json` file in the same package as the test
// assertThat(this.json.write(details)).isEqualToJson("expected.json");
}
@Test
public void testDeserialize() throws Exception {
String content = "{\"id\":1,\"name\":\"Ford\",\"age\":8,\"address\":\"Focus\"}";
// assertThat(this.json.parse(content)).isEqualTo(new User(1L,"Ford",8, "Focus"));
assertThat(this.json.parseObject(content).getName()).isEqualTo("Ford");
}
}
七 http请求测试
package com.example.mvctest;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class HttpRequestTest {
@LocalServerPort
private int port;
@Autowired
private TestRestTemplate restTemplate;
@Test
public void greetingShouldReturnDefaultMessage() throws Exception {
assertThat(this.restTemplate.getForObject("http://localhost:" + port + "/",
String.class)).contains("Hello, World");
}
}
七 参考文档
https://spring.io/guides/gs/testing-web/
https://www.baeldung.com/spring-boot-testing
https://docs.spring.io/spring-boot/docs/1.5.7.RELEASE/reference/html/boot-features-testing.html
后期继续补充使用,初步整理使用记录,继续提升单元测试覆盖率,结合阿里java开发规约中单元测试相关内容理解使用.
测试代码连接: https://github.com/wangrqsh/mvctest_learn.git
来源:oschina
链接:https://my.oschina.net/u/4312036/blog/4303627