使用 Spring 引导测试 REST 控制器的 Spock 测试框架
Spock Testing Framework with Spring Boot to test REST Controller
我已经使用 spring 引导编写了 rest api 这是控制器代码
@RestController
public class ApiController {
@Autowired
private ApiService apiService;
@PostMapping(path = "/user", consumes = {MediaType.APPLICATION_JSON_VALUE},
produces = {MediaType.APPLICATION_JSON_VALUE})
@LogTransaction
public ResponseEntity<String> user(HttpServletRequest request) {
//apiService.getUser() method call database so i need to mock it
USer user = apiService.getUser(request);
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(user);
}
}
这个 api 工作正常,我已经在 groovy
中使用 spock 框架编写了测试
@SpringBootTest
class ApiControllerTest extends Specification {
@Autowired
private ApiController apiController;
@Autowired
private ApiService apiService;
@Autowired
MockMvc mockMvc
def "User api"() {
given:
def User user = new User()
apiService.getUser(_) >> user
when:
def result = mockMvc.perform(MockMvcRequestBuilders
.post("/user")
.contentType(MediaType.APPLICATION_JSON)
.content("""
{
"username":"demo",
"password":"demo"
}
"""))
.andReturn()
then:
assert result.response.status == HttpStatus.OK.value()
}
这也很好用。方法 apiService.getUser(请求) 调用数据库。我想嘲笑它。但它每次都在调用数据库。因此,我尝试在此处使用 @Autowired 模拟 apiService.getUser(request),但它对我不起作用,并且此方法每次都执行并调用数据库。任何人都可以分享模拟控制器的 apiService.getUser(request) 方法的方法。
您可以对
这样的数据源使用排除
@SpringBootTest
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
@AutoConfigureMockMvc
public class Class1Test{
@Autowired
private MockMvc mockMvc;
@MockBean
private RestTemplate restTemplate;
@MockBean
private IYourRepository repository;
@Autowired
private SecurityJwtSettings securityJwtSettings;
使用 mockito,您可以模拟对数据库的请求:
Mockito.doAnswer(x->{
YourEntity entityToSave = x.getArgument(0);
entityToSave.setCreatedAt(LocalDateTime.now());
Assert.assertEquals("tester.admin.01",entityToSave.getAuthorizedBy());
Assert.assertEquals("tester.01", entityToSave.getRequestedBy());
return entityToSave;
}).when(repository).save(Mockito.any(YourEntity.class));
您可以通过使用 @SpringSpy
.
注释来部分模拟 spring 个 bean
因此,在您的情况下,您只需将 @Autowired
替换为 @SpringSpy
:
@SpringSpy
private ApiService apiService;
它应该可以工作。
我已经使用 spring 引导编写了 rest api 这是控制器代码
@RestController
public class ApiController {
@Autowired
private ApiService apiService;
@PostMapping(path = "/user", consumes = {MediaType.APPLICATION_JSON_VALUE},
produces = {MediaType.APPLICATION_JSON_VALUE})
@LogTransaction
public ResponseEntity<String> user(HttpServletRequest request) {
//apiService.getUser() method call database so i need to mock it
USer user = apiService.getUser(request);
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(user);
}
}
这个 api 工作正常,我已经在 groovy
中使用 spock 框架编写了测试 @SpringBootTest
class ApiControllerTest extends Specification {
@Autowired
private ApiController apiController;
@Autowired
private ApiService apiService;
@Autowired
MockMvc mockMvc
def "User api"() {
given:
def User user = new User()
apiService.getUser(_) >> user
when:
def result = mockMvc.perform(MockMvcRequestBuilders
.post("/user")
.contentType(MediaType.APPLICATION_JSON)
.content("""
{
"username":"demo",
"password":"demo"
}
"""))
.andReturn()
then:
assert result.response.status == HttpStatus.OK.value()
}
这也很好用。方法 apiService.getUser(请求) 调用数据库。我想嘲笑它。但它每次都在调用数据库。因此,我尝试在此处使用 @Autowired 模拟 apiService.getUser(request),但它对我不起作用,并且此方法每次都执行并调用数据库。任何人都可以分享模拟控制器的 apiService.getUser(request) 方法的方法。
您可以对
这样的数据源使用排除@SpringBootTest
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
@AutoConfigureMockMvc
public class Class1Test{
@Autowired
private MockMvc mockMvc;
@MockBean
private RestTemplate restTemplate;
@MockBean
private IYourRepository repository;
@Autowired
private SecurityJwtSettings securityJwtSettings;
使用 mockito,您可以模拟对数据库的请求:
Mockito.doAnswer(x->{
YourEntity entityToSave = x.getArgument(0);
entityToSave.setCreatedAt(LocalDateTime.now());
Assert.assertEquals("tester.admin.01",entityToSave.getAuthorizedBy());
Assert.assertEquals("tester.01", entityToSave.getRequestedBy());
return entityToSave;
}).when(repository).save(Mockito.any(YourEntity.class));
您可以通过使用 @SpringSpy
.
因此,在您的情况下,您只需将 @Autowired
替换为 @SpringSpy
:
@SpringSpy
private ApiService apiService;
它应该可以工作。