单体测试中Validator的测试
private Validator validator;
@Before
public void setUp() {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
validator = factory.getValidator();
}
@Test
public void test1() {
var dto = ...
var violations = validator.validate(dto);
assertThat(violations.isEmpty()).isTrue();
}
单体测试中的Controller测试
@RunWith(SpringRunner.class)
@WebMvcTest(controllers = MyController.class)
@ContextConfiguration(classes = {MyApplication.class, MyConfig.class, ...})
@TestPropertySource(locations = {"classpath:/my-local.yml", "classpath:/application.properties"})
public class MyControllerUnitTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private MyService myService;
@Autowired
// com.fasterxm.jackson.databind.ObjectMapper
private ObjectMapper mapper;
@Test
// 使用spring security做鉴权,在配置类里模拟出来测试用的UserDetailsService
// 实现public UserDetails loadUserByUsername(String username)提供模拟的用户
@WithUserDetails(value = "username1")
public void test1() {
// 可以获取登录用户信息用于后续测试
var principal = (PrincipalDetails)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
//
when(this.myService.method1(an(MyBean.class)).thenReturn(someObj);
this.mockMvc.perform(
post("/mypath/myapi")
.contentType(MediaType.APPLICATION_JSON)
.content(this.mapper.writeValuesAsString(myRequestObj)))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$.[0].name").value("expectName"))
.andExpect(jsonPath("$.message").exists())
.andExpect(jsonPath("$.errors").doesNotExists());
verify(this.myServie, times(1)).method1(an(MyBean.class));
verify(this.myServie, never()).method2(an(MyBean.class));
}
}
功能测试中使用WebTestClient
@Sql("/path/to/file/test0.sql")
@RunWith(SpringRunner.class)
@SpringBootTest(classes=MyApplication.class, webEnvironment=WebEnvironment.RANDOM_PORT)
@TestPropertySource(locations={"classpath:/my-local.yml", "classpath:/application.properties"})
public class UserApplicationTest {
@Autowired
private WebTestClient webTestClient;
@Autowired
private ObjectMapper objectMapper;
@LocalServerPort
private int port;
@Before
public void setupClient() {
var client = WebClient.builder()
.baseUrl("http://localhost:" + this.port)
.filter(ExchangeFilterFunctions.basicAuthentication("user", "pass"))
.build();
var token = client.get().uri("/login").exchange().block().headers().header("X-Auth-Token").get(0);
this.webTestClient = WebTestClient.bindToServer()
.baseUrl("http://localhost:" + this.port)
.defaultHeader("X-Auth-Token", token)
.build();
}
@Test
@Sql("/path/to/file/test1.sql")
public void test1() {
ObjectNode requestObj = (ObjectNode) this.objectMapper.readTree(ResourceUtils.getFile("classpath:/path/to/file/test1.json"));
this.webTestClient.post()
.uri("/path/method1")
.contentType(MediaType.APPLICATION_JSON)
.body(Mono.just(requestObj.toString()), String.class)
.exchange()
.expectStatus().isOk()
.expectHeader().contentType(MediaType.APPLICATION_JSON)
.expectBody()
.jsonPath("$.field1").exists()
.jsonPath("$.field2").isEqualTo(requestObj.get("field2").asText())
.jsonPath("$..field3").isArray();
}
}
JPA仓库测试
@RunWith(SpringRunner.class)
@DataJpaTest
@AutoConfigureTestDatabase(replace = Replace.NONE)
@TestPropertySource(locations = {"classpath:/my-local.yml", "classpath:/application.properties"})
public class MyRepositoryTest {
@Autowired
private MyRepository myRepository;
@Test
public void test1() {
// 创建bean对象
var myObj = ...;
var savedObj = this.myRepository.save(myObj);
var ret = this.myRepository.existsByIdAndField1(savedObj.getId(), myObj.getField1());
assertThat(ret).isTrue();
}
}
可以使用MockHttpServletRequest模拟请求
MockHttpServletRequest request = new MockHttpServletRequest();
request.addHeader("field1", "field1 value");
RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request));