【发布时间】:2020-04-25 22:12:42
【问题描述】:
我正在学习为 SpringBoot Restcontroller 编写单元测试,写了这个并且测试通过了
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {FhirApp.class, TestSecurityConfiguration.class})
@AutoConfigureMockMvc
public class ObservationControllerTest {
private ObjectMapper objectMapper = new ObjectMapper();
@Autowired
private MockMvc mockMvc;
@MockBean
private ObservationService observationService;
@Test
public void createObservationResource() throws Exception {
given(observationService.createObservation(ResourceStringProvider.observationsource()))
.willReturn(responseDocument);
String jsonString = objectMapper.writeValueAsString(
ResourceStringProvider.observationsource());
mockMvc.perform(post("/Observation")
.contentType(MediaType.APPLICATION_JSON)
.content(jsonString))
.andExpect(status()
.isOk());
}
但是作为 this 和 this ,我也得到了 response.getContentAsString() 的空响应:
Mockito.when(observationService.createObservation(Mockito.any())).thenReturn(responseDocument);
String jsonString = objectMapper.writeValueAsString(ResourceStringProvider.observationsource());
MockHttpServletResponse response = mockMvc.perform(post("/Observation")
.contentType(MediaType.APPLICATION_JSON)
.content(jsonString))
.andReturn()
.getResponse();
assertThat(response.getContentAsString())
.isEqualTo(new ObjectMapper()
.writeValueAsString(responseDocument));
我已经尝试过他们提供的解决方案:
1: Using Mockito.any(String.class)
2: webEnvironment = SpringBootTest.WebEnvironment.MOCK
3: using thenCallRealMethod instead of thenReturn(responseDocument)
但不幸的是它没有用,已经尝试了不同的可能性,我也尝试过使用 MockitoJunitRunner :
@RunWith(MockitoJUnitRunner.class)
@SpringBootTest(classes = {FhirApp.class, TestSecurityConfiguration.class})
@AutoConfigureMockMvc
public class ObservationControllerTest {
private MockMvc mockMvc;
@Mock
private ObservationService observationService;
@Mock
private RequestFilter requestFilter;
@InjectMocks
private ObservationController observationController;
@Before
public void setup() {
Resource resource = Utility.convertFromStringToFhirResource(Observation.class,ResourceStringProvider.observationResponse());
responseDocument=Utility.convertFromFhirResourceToMongoInsertibleDoc(resource);
//these line enabled for MockitoJUnitRunner only
this.mockMvc = MockMvcBuilders.standaloneSetup(observationController)
.setControllerAdvice(new FhirRuntimeException("Error Happened"))
.addFilters(requestFilter)
.build();
}
@Test
public void createObservationResource()throws Exception{
Mockito.when(observationService.createObservation(ResourceStringProvider.observationsource())).thenReturn(responseDocument);
String jsonString = objectMapper.writeValueAsString(ResourceStringProvider.observationsource());
MockHttpServletResponse response = mockMvc.perform(
post("/Observation")
.contentType(MediaType.APPLICATION_JSON)
.content(jsonString))
.andReturn()
.getResponse();
assertThat(response.getContentAsString()).isEqualTo(new ObjectMapper().writeValueAsString(responseDocument));
}
我认为由于没有多少人经历过这样的问题,所以没有太多谈论这个问题。响应状态正常时响应为空的原因是什么?
控制器代码:
@RestController
@RequestMapping("/api")
public class ObservationController {
@Autowired
private ObservationService observationService;
@GetMapping("/Observation/{id}")
public ResponseEntity<Document> getObservationByID(
@RequestParam("_pretty") Optional<String> pretty,
@PathVariable("id") String id) {
Document resultDoc = observationService.getObservationById(id);
return new ResponseEntity<>(resultDoc, HttpStatus.OK);
}
@PostMapping(path = "/Observation", consumes = {"application/json", "application/fhir+json"},
produces = {"application/json", "application/fhir+json"})
public ResponseEntity<Document> createObservationResource(@RequestBody String fhirResource) {
Document fhirDoc = observationService.createObservation(fhirResource);
return new ResponseEntity<>(fhirDoc,
Utility.createHeaders(fhirDoc),
HttpStatus.CREATED);
}
//other methods
}
我意识到在测试中发布的调用应该是 /api/Observation ,但它没有任何区别。提前致谢。
【问题讨论】:
-
当你调试你的测试时,你发现了什么问题?如果您有一个空结果,那么您返回给客户端的任何内容都是空的。但是你还没有发布你的服务器端代码是什么样的,所以我们不知道。
-
我已经更新了控制器的代码。实际上整个项目是使用 Jhipster 生成的 Spring-Boot 项目。
-
什么时候调试你的测试?你能验证
Document fhirDoc不为空吗? -
这可能是因为
ResourceStringProvider.observationsource()创建了不同的对象,当您在模拟中使用它们时这些对象不匹配。你可以尝试重写equals方法。 -
基于您的 cmets 我使用 Mockito.verify() 检查并且控制器本身没有以某种方式被调用。这颗宝石thepracticaldeveloper.com/2017/07/30/… 也帮了很多忙。
标签: java spring-boot spring-boot-test