ResourceAccessException:POST请求发生I / O错误

问题描述 投票:0回答:1

我有一种服务方法。该方法是通过POST请求访问第三方资源。我正在编写测试,但在日志中看到错误。服务:

@Override
public void sendDoc(String id) throws IOException {
    byte[] zipData = getZipFromIntegration(mongo.getDocument());

    String response;
    HttpStatus httpStatus;
    try {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);

        LinkedMultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
        map.add("file", new MultipartInputStreamFileResource(new ByteArrayInputStream(zipData),
                String.format("%s_some.zip", id)));

        HttpEntity<LinkedMultiValueMap<String, Object>> requestEntity = new HttpEntity<>(map, headers);

        HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();
        clientHttpRequestFactory.setConnectTimeout(3000);
        clientHttpRequestFactory.setReadTimeout(3000);
        RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory);

        response = restTemplate.postForObject(uploadUrl + system,
                requestEntity, String.class);

    } catch (HttpStatusCodeException e) {
        LOG.error("Some error");
    }
}

我的测试

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = NONE, classes = {SendServiceImpl.class})
@EnableAutoConfiguration
@PropertySource(value = "classpath:application.properties", encoding = "UTF-8")
public class SendServiceImplTest {
    @MockBean
    private RestTemplate restTemplate;
    @Autowired
    private SendServiceImpl service;

    @Test
    public void sendDoc() throws IOException {
        when(restTemplate.postForObject(
                anyString(),
                ArgumentMatchers.<HttpEntity<?>>any(),
                ArgumentMatchers.<Class<String>>any()
        ))
                .thenReturn("ok");

        service.sendDoc("55454545uid");
    }
}

但是我看到有一个到真实服务器的电话。测试成功,但是在日志中看到错误:

org.springframework.web.client.ResourceAccessException:I / O错误出现在 POST请求“ [http://some-url.digital.cloud.ru/v1/doc/reg

UPD:像这样更改测试:

@RunWith(PowerMockRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK, classes = SendServiceImpl.class)
@PowerMockRunnerDelegate(SpringRunner.class)
@PrepareForTest({SendServiceImpl.class, RestTemplate.class})
@PowerMockIgnore({"javax.xml.*", "org.xml.sax.*", "org.w3c.dom.*"})
public class SendServiceImplTest {
    @MockBean
    private RestTemplate restTemplateMock;

    @Autowired
    private SendServiceImpl service;

    @Test
    public void sendDoc() throws IOException {
    RestTemplate restTemplate = PowerMockito.mock(RestTemplate.class);
    whenNew(RestTemplate.class).withArguments(ClientHttpRequestFactory.class).thenReturn(restTemplate);
    when(restTemplate.postForObject(
                anyString(),
                ArgumentMatchers.<HttpEntity<?>>any(),
                ArgumentMatchers.<Class<String>>any()
        ))
                .thenReturn("ok");

        service.sendDoc("55454545uid");
    }
}

现在对象将替换为null。也就是说,服务中的restTemplate为null。

java unit-testing junit resttemplate
1个回答
0
投票

我的问题的解决方案如下:

@RunWith(PowerMockRunner.class)
@SpringBootTest(webEnvironment = NONE, classes = SendServiceImpl.class)
@PowerMockRunnerDelegate(SpringRunner.class)
@PrepareForTest({
        SendServiceImpl.class,
        RestTemplate.class,
        HttpComponentsClientHttpRequestFactory.class
})
@MockBean({FileStorageService.class, DocxToPdfConverterService.class})
@PowerMockIgnore({"javax.xml.*", "org.xml.sax.*", "org.w3c.dom.*"})
public class SendServiceImplTest {
    @Test
    public void sendDoc() throws Exception {
        RestTemplate restTemplate = Mockito.mock(RestTemplate.class);

        whenNew(RestTemplate.class).withAnyArguments().thenReturn(restTemplate);

        PowerMockito.when(restTemplate.postForObject(
                anyString(),
                ArgumentMatchers.<HttpEntity<?>>any(),
                ArgumentMatchers.<Class<String>>any()
        )).thenReturn("ok");
    }
// ......any code.......
}

[PowerMock库和withAnyArguments()方法帮助了我。

© www.soinside.com 2019 - 2024. All rights reserved.