JUNIT - RestTemplate - 连接到实际 URL

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

团队

我的服务将作为独立程序运行,

我的代码:

public class TestRestTemplate {
    private RestTemplate restTemplate;

    public TestRestTemplate() {
        restTemplate = new RestTemplate();
    }

    public void identifyInvoiceCategory(final Properties properties) throws Throwable {
        final ResponseEntity<SearchResponse> exchange = restTemplate.exchange(
                properties.getProperty("ENDPOINT"), HttpMethod.GET,
                new HttpEntity<>(createSearchRequest(), createHttpHeader()), SearchResponse.class);

        final SearchResponse searchResponse = exchange.getBody();
        searchResponse.getEndIndex();
    }

    private SearchRequest createSearchRequest() throws Throwable {
        final SearchRequest searchRequest = new SearchRequest();
        return searchRequest;
    }

    private HttpHeaders createHttpHeader() {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);
        return httpHeaders;
    }
}

我的 Junit 测试代码


@RunWith(MockitoJUnitRunner.class)

public class TestRest {
    @Mock
    private RestTemplate restTemplate;

    @Test

    public void testIdentifyInvoiceCategoryValid() throws Throwable {
        try {
            Mockito.when(restTemplate.exchange(ArgumentMatchers.anyString(), ArgumentMatchers.eq(HttpMethod.GET),
                    ArgumentMatchers.any(), ArgumentMatchers.<Class<SearchResponse>>any())).thenReturn(null);
            new TestRestTemplate().identifyInvoiceCategory(createProperties());

        } catch (Throwable genThrowable) {
            genThrowable.printStackTrace();
        }
    }

    private Properties createProperties() {
        final Properties properties = new Properties();
        properties.setProperty("ENDPOINT", "http://www.test.com");
        return properties;
    }
}

当我运行 JUNIT 时,出现以下异常


org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://www.test.com": Connection timed out: connect; nested exception is java.net.ConnectException: Connection timed out: connect
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:791)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:717)
    at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:608)
    at com.gxs.orch.aggregator.util.TestRestTemplate.identifyInvoiceCategory(TestRestTemplate.java:23)

看起来,它正在尝试连接到实际的 URL,而不是 Mocking...

你能帮我解决这个问题吗?

spring-boot junit4 junit5
1个回答
0
投票

您嘲笑了

RestTemplate
,但在测试中您实际上没有将其注入到
TestRestTemplate
中。因此,
TestTestTemplate
正在使用您在构造函数中创建的
RestTemplate

第一步是将您的模拟注入

TestRestTemplate
。最简单的方法是使用
@InjectMocks
注释:

@RunWith(MockitoJUnitRunner.class)
public class TestRest {
    // Add this field:
    @InjectMocks
    private TestRestTemplate testRestTemplate;
    @Mock
    private RestTemplate restTemplate;

    // ...
}

之后,您必须重构您的测试,以便它们使用 Mockito 创建的

TestRestTemplate
实例,而不是使用您自己的实例。这意味着无论您在哪里使用
new TestRestTemplate()
,您现在都指的是
testRestTemplate
字段。

例如:

@Test
public void testIdentifyInvoiceCategoryValid() throws Throwable {
    // ...
    // Don't use new TestRestTemplate():
    testRestTemplate.identifyInvoiceCategory(createProperties());
    // ...
}

此外,虽然

@InjectMocks
的工作并不是必需的,但在
RestTemplate
的构造函数中创建新的
TestRestTemplate
实例被认为是一种不好的做法,因为它会增加耦合。要解决此问题,您可以重构构造函数以接受外部
RestTemplate
实例:

public class TestRestTemplate {
    private RestTemplate restTemplate;

    // Refactor your constructor to this:
    public TestRestTemplate(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

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