使用 restAssured 测试 Spring Boot Rest 应用程序

Posted

技术标签:

【中文标题】使用 restAssured 测试 Spring Boot Rest 应用程序【英文标题】:testing spring boot rest application with restAssured 【发布时间】:2017-04-01 14:38:34 【问题描述】:

我已经为此苦苦挣扎了一段时间。 我想使用 restAssured 来测试我的 SpringBoot REST 应用程序。

虽然看起来容器正常旋转,但请放心(其他任何东西似乎都无法触及它。

我总是收到 Connection denied 异常。

java.net.ConnectException: Connection refused

at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
...

我的测试课:

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

    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    public void test() 
        System.out.println(this.restTemplate.getForEntity("/clothes", List.class));
    

    @Test
    public void test2() throws InterruptedException 
        given().basePath("/clothes").when().get("").then().statusCode(200);
    


现在对于奇怪的部分,test 传递并打印了它应该传递的内容,但 test2 得到了 Connection refused 异常。

你知道这个设置有什么问题吗?

【问题讨论】:

【参考方案1】:

"/clothes" 作为参数传递给 get() 方法应该可以解决问题

@Test
public void test2() throws InterruptedException 
    when().
        get("/clothes").
    then().
        statusCode(200);

【讨论】:

不幸的是这并没有改变任何东西【参考方案2】:

你是不是运行在一些非标准的端口上? 你有没有在你的

@Before public static void init() RestAssured.baseURI = "http://localhost"; // replace as appropriate RestAssured.port = 8080;

【讨论】:

SpringBootTest.WebEnvironment.RANDOM_PORT 导致应用每次在不同的端口上运行 那么可能是,`@Value("$local.server.port") int port; @Before public static void init() RestAssured.baseURI = "localhost"; // 酌情替换 RestAssured.port = port; `【参考方案3】:

我会自己回答这个问题..

在花费了额外的时间之后,事实证明TestRestTemplate 已经知道并设置了正确的端口。 RestAssured 不会...

这样我就达到了以下测试运行没有任何问题的地步。

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

    @LocalServerPort
    int port;

    @Before
    public void setUp() 
        RestAssured.port = port;
    

    @Test
    public void test2() throws InterruptedException 
        given().basePath("/clothes").get("").then().statusCode(200);
    


我本可以发誓我以前尝试过这样做......但我想我确实使用了其他一些注释......

【讨论】:

请注意,在 Spring 2 中,只需稍作修改即可使用:@ExtendWith(SpringExtension.class) 代替 RunWith@BeforeEach 代替 Before,当使用 Junit5 (Jupiter) 时。 这个和其他答案没有考虑到使用 RANDOM_PORT 会杀死 Spring Test 的事务管理。 @Transactional 将不起作用,测试将不再被隔离。从长远来看,这将带来问题。 docs.spring.io/spring-boot/docs/2.1.5.RELEASE/reference/html/…【参考方案4】:

简单地说:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.DEFINED_PORT)
public class CommonScenarioTest 

    @BeforeClass
    public static void setup() 
        RestAssured.baseURI = "http://localhost/foo";
        RestAssured.port = 8090;
    

【讨论】:

【参考方案5】:

基于https://***.com/users/2838206/klubi 的回答并且不为您发出的每个请求设置端口:

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

    @LocalServerPort
    int port;

    @Before
    public void setUp() 
        RestAssured.port = port;
    

    @Test
    public void test2() throws InterruptedException 
        given().basePath("/clothes").get("").then().statusCode(200);
    

【讨论】:

请注意,在 Spring 2 中,只需稍作修改即可使用:@ExtendWith(SpringExtension.class) 代替 RunWith@BeforeEach 代替 Before 使用 Junit5 (Jupiter)。【参考方案6】:

我建议在这种情况下使用@WebMvcTest,你只需要放心地模拟 mvc 依赖:

<dependency>
            <groupId>com.jayway.restassured</groupId>
            <artifactId>spring-mock-mvc</artifactId>
            <version>$rest-assured.version</version>
            <scope>test</scope>
</dependency>

使用@SpringBootTest 仅测试一个控制器是开销,所有冗余bean,如@Component@Service 等,都将被创建并 将启动完整的 HTTP 服务器。更多细节: https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#boot-features-testing-spring-boot-applications-testing-autoconfigured-mvc-tests;

  @RunWith(SpringRunner.class)
  @WebMvcTest(value = SizesRestController.class)
  public class SizesRestControllerIT 

     @Autowired
     private MockMvc mvc;

     @Before
     public void setUp() 
        RestAssuredMockMvc.mockMvc(mvc);
     

     @Test
     public void test() 
        RestAssuredMockMvc.given()
           .when()
           .get("/clothes")
           .then()
           .statusCode(200);
        // do some asserts
     
 

【讨论】:

现在您使用模拟/单元(容器外)测试,但问题是如何进行集成(端到端)测试【参考方案7】:

我遇到了同样的问题,服务器在端口 34965(不是 8080)上运行应用程序。 这解决了我的问题:

@Autowired
ServerProperties serverProperties;

@Autowired
Environment environment;

public String getPath() 
    final int port = environment.getProperty("local.server.port", Integer.class);

    return "http://localhost:" + port;


@Before
public void setUp() throws Exception 
    RestAssured.baseURI = getPath();


@Test
public void testResponse()
    response = get("/books");

【讨论】:

【参考方案8】:

您似乎正在尝试为 Spring Web App 编写集成测试。 REST-assured Support for Spring MockMvc on Baeldung 提供有关如何执行此操作的信息。

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
public class SizesRestControllerIT 

    @Autowired
    private WebApplicationContext webApplicationContext;

    @Before
    public void initialiseRestAssuredMockMvcWebApplicationContext() 
        RestAssuredMockMvc.webAppContextSetup(webApplicationContext);
    

    @Test
    public void test2() throws InterruptedException 
        given().basePath("/clothes").get("").then().statusCode(200);
    

Baeldung 中没有提到的是 Spring 的静态导入更改。 REST-Assured Docs on Bootstrapping SpringImport issues mentioned in another ***

确保你使用:

import static io.restassured.module.mockmvc.RestAssuredMockMvc.*;
import static io.restassured.module.mockmvc.matcher.RestAssuredMockMvcMatchers.*;

不要与 Spring 一起使用:

import static io.restassured.RestAssured.*;
import static io.restassured.matcher.RestAssuredMatchers.*;

使用错误的导入可能会导致连接被拒绝异常。

【讨论】:

以上是关于使用 restAssured 测试 Spring Boot Rest 应用程序的主要内容,如果未能解决你的问题,请参考以下文章

java接口自动化测试--restassured如何进行文件上传接口测试

Spring Boot测试中使用REST Assured(转)

restAssured 测试接口,以下是一个get 请求。

RestAssured 中的无效 JSON Schema 异常,同时针对来自 swagger 的模式进行验证

RestAssured API测试框架中的否定断言或否定匹配[关闭]

一文搞定自动化测试框架 RESTAssured 实践:对 Response 结果导出