如何解决Junit 测试失败:HttpMessageConversion 错误
我正在尝试使用 JUnit
作为剩余 url 为以下类编写 Mockito
测试用例。
@Override
public void sendWebhook(WebRequest webRequest) {
ResponseEntity<Object> webresponse = restService.sendWebhook(webRequest);
}
restServiceImpl
@Override
public ResponseEntity<Object> sendWebhook(WebRequest webRequest) {
ResponseEntity<Object> response = null;
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
httpentity<webRequest> request = new httpentity<>(webRequest,headers);
try {
response = restTemplate.exchange(webRequest.getUrl(),HttpMethod.POST,request,Object.class);
} catch (ResourceAccessException resourceAccessException) {
return null;
}
return response;
}
使用 Mockito
进行上述类的单元测试
@RunWith(springrunner.class)
@SpringBoottest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class WebServiceImpltest {
@Autowired
private RestTemplate restTemplate;
private MockRestServiceServer mockServer;
@Autowired
private RestService restService;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mockServer = MockRestServiceServer.createServer(restTemplate);
}
@Test
public void testSendWebhookWithSuccess() throws Exception {
/* setup mock */
WebRequest webRequest = mock(WebRequest.class);
Mockito.when(restService.sendWebhook(webRequest))
.thenReturn(new ResponseEntity<Object>(HttpStatus.OK));
UriComponents uriComponents =
UriComponentsBuilder.fromUriString("http://localhost:8080/mockWeb/sendSuccessMsg").build();
mockServer.expect(requestTo(uriComponents.toUriString())).andExpect(method(HttpMethod.POST))
.andRespond(withSuccess("Success",MediaType.APPLICATION_JSON));
mockServer.verify();
}
}
当我在测试用例之上运行时,我得到,
Results :
Tests in error:
testSendWebhookWithSuccess » HttpMessageConversion
Tests run: 1,Failures: 0,Errors: 1,Skipped: 0
我遇到了错误
Mockito.when(restService.sendWebhook(webRequest))
.thenReturn(new ResponseEntity<Object>(HttpStatus.OK));
为什么我会遇到上述错误。我能知道我错过了什么吗
stackTrace 下面附上
Tests run: 1,Skipped: 0,Time elapsed: 38.087 sec <<< FAILURE! - in ...web.service.impl.WebServiceImpltest
testSendWebhookWithSuccess(...service.impl.WebServiceImpltest) Time elapsed: 0.321 sec <<< ERROR!
org.springframework.http.converter.HttpMessageConversionException: Type deFinition error: [simple type,class org.mockito.internal.invocation.mockref.MockWeakReference]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDeFinitionException: No serializer found for class org.mockito.internal.invocation.mockref.MockWeakReference and no properties discovered to create BeanSerializer (to avoid exception,disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.equifax.mortgage.udm.webhook.model.WebRequest$MockitoMock$1970556850["mockitoInterceptor"]->org.mockito.internal.creation.bytebuddy.MockMethodInterceptor["mockHandler"]->org.mockito.internal.handler.InvocationNotifierHandler["invocationContainer"]->org.mockito.internal.stubbing.InvocationContainerImpl["invocationForStubbing"]->org.mockito.internal.invocation.InvocationMatcher["invocation"]->org.mockito.internal.invocation.InterceptedInvocation["mockRef"])
at com.fasterxml.jackson.databind.exc.InvalidDeFinitionException.from(InvalidDeFinitionException.java:77)
at com.fasterxml.jackson.databind.SerializerProvider.reportBadDeFinition(SerializerProvider.java:1277)
at com.fasterxml.jackson.databind.DatabindContext.reportBadDeFinition(DatabindContext.java:400)
at com.fasterxml.jackson.databind.ser.impl.UnkNownSerializer.failForEmpty(UnkNownSerializer.java:71)
at com.fasterxml.jackson.databind.ser.impl.UnkNownSerializer.serialize(UnkNownSerializer.java:33)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializefields(BeanSerializerBase.java:755)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializefields(BeanSerializerBase.java:755)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializefields(BeanSerializerBase.java:755)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializefields(BeanSerializerBase.java:755)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializefields(BeanSerializerBase.java:755)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializefields(BeanSerializerBase.java:755)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319)
at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1516)
at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:1006)
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:343)
at org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:104)
at org.springframework.web.client.RestTemplate$httpentityRequestCallback.doWithRequest(RestTemplate.java:943)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:737)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:674)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:583)
at ...web.service.impl.RestServiceImpl.sendWebhook(RestServiceImpl.java:50)
解决方法
这意味着当您只能使用真实对象执行此操作时,您的模拟对象正在经历适当的 jackson 反序列化。
就您而言,我认为问题在于 new ResponseEntity<Object>(...)
:它不是真正的可序列化对象。
为您的 thenReturn(thisBetterBeSerializable)
创建一些具体的东西,因为它显然在嵌套服务调用中的某个地方通过 jackson。
当我在 spring 控制器测试中创建一个模拟对象作为响应时,我得到了那个确切的异常(“没有为类 org.mockito.internal.invocation.mockref.MockWeakReference 和...找到序列化程序”):
我有这个(释义)
@MockBean
private MyService myService;
@Test
public void test_200Returned() throws Exception {
MyRealResponseType mockResponse = Mockito.mock(MyRealResponseType.class); // WRONG!
when(myService.myMethod(any(MyRequest.class))).thenReturn(mockResponse);
this.mockMvc.perform(post("/my/service/api")).andExpect(status().isOk());
}
一切正常,直到我的控制器类(为 /my/service/api 提供服务的类)在调用 myService.myMethod
以获取对象后尝试返回该对象。 mockResponse 对象被返回(按计划),但 Jackson 无法处理它。
我通过将 Mockito.mock
行替换为以下内容解决了我的问题:
MyRealResponseType mockResponse = new MyRealResponseType(); // RIGHT!
mockResponse.setSomeNeededPropertyJustInCase("someValue");
...
然后一切顺利,我的测试通过了。
您的情况略有不同,但我怀疑如果您创建一个真实的对象来传递到 thenReturn
,您的问题就会消失。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。