微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Junit 测试失败:HttpMessageConversion 错误

如何解决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] 举报,一经查实,本站将立刻删除。