在测试中公开端点URL

时间:2018-09-24 14:04:58

标签: java spring-boot testing

我们直接解决这个问题:

我想测试一个将Rest端点的URL作为参数的方法。该方法在内部使用RestTemplate向该URL发送请求,因此它必须是完整的URL,例如http://localhost:8080/rest。因此,我也无法模拟RestTemplate

我想创建简单的@RestController,但似乎Spring在运行测试时没有创建端点。

我尝试创建MockMvc,但这不是我想要的。我无法获取MockMvc创建的端点的IP和端口,因为没有创建实际的端点。

因此,我想要的是通过向URL发送请求来使我的@RestController在测试中可访问,例如:http://localhost:8080/rest

这是我第一次创建这样的测试,感谢您的帮助。我在寻找答案,但是找不到解决我问题的方法。

编辑: 这是一些代码:

不幸的是,我无法发布所有代码,但是我发布的内容应该足够了:

我的端点是(名称更改):

@RestController
public class EndpointController {

    @RequestMapping(value = "/rest", method = RequestMethod.POST)
    public List<Output> doSomething(@RequestBody Input[] requestList){
        ...
    }

}

仅用于测试的端点,它模仿真实的端点。然后在测试期间,我正在创建一个像这样的对象:

new EndpointClient("http://localhost:8080/rest")

里面有这样的东西:

ResponseEntity<Output[]> responseEntity = restTemplate.exchange(endpointURL,HttpMethod.POST, httpEntity, Output[].class);

具有restTemplate请求的方法不会在测试期间直接调用(由另一种方法调用)。

所以我需要将该URL传递给Client对象。

2 个答案:

答案 0 :(得分:0)

如果要测试Web应用程序,请查看Getting Started: Testing the Web Layer文档。

Spring Boot提供了一些有用的注释,例如@SpringBootTest@AutoConfigureMockMvc,... 另请参见TestRestTemplate,它可以自动连接到WebMvcTest。

修改: 一个示例,从上面提到的文档复制而来:

package hello;

import org.junit.Test;
import org.junit.runner.RunWith;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.test.context.junit4.SpringRunner;

import static org.assertj.core.api.Assertions.assertThat;

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class HttpRequestTest {

@LocalServerPort
private int port;

@Autowired
private TestRestTemplate restTemplate;

@Test
public void greetingShouldReturnDefaultMessage() throws Exception {
    assertThat(this.restTemplate.getForObject("http://localhost:" + port + "/",
            String.class)).contains("Hello World");
    }
}

答案 1 :(得分:0)

我找到了解决问题的方法。

我使用WireMock做到了:http://wiremock.org/

首先,我必须为我的请求创建Transformer,因此响应取决于请求,例如:

public class MyTransformer extends ResponseTransformer {

    @Override
    public Response transform(final Request request,
                              final Response response,
                              final FileSource fileSource,
                              final Parameters parameters){
        HttpHeaders headers = new HttpHeaders(new HttpHeader("Content-Type", "application/json"));
        if(request.getUrl().contains("/rest")){
            ...
            return Response.Builder.like(response).but().body(...).headers(headers).build();
        } else
            return Response.Builder.like(response).but().status(404).headers(headers).build();
    }

    @Override
    public String getName() {
        return "swapper";
    }
}

在测试中,我需要放

WireMockServer server = new WireMockServer(wireMockConfig().port(3665).extensions("package.name.endpoint.MyTransformer"));
server.stubFor(post("/rest"));

它正是我想要的。上面的代码非常简单,可能不是很好,需要工作,但它显示了基础。