简体   繁体   中英

How to extract cookies from a REST Assured response using common code

Using REST Assured (4.3.3, from Java) I can freely manipulate request and response specification objects in a base test class, so that when the actual test needs a request specification to execute the actual call, it's "pre-configured" with certain common statements. For example:

public abstract class TestBase
    protected RequestSpecification request() {
        return given()
                .cookies(globalCookies)
                .port(serverPort)
                .log().ifValidationFails()
                .then()
                .log().ifValidationFails()
                .given();
    }
}
public class ActualTest extends TestBase {
  @Test
  public void test1() {
    String content = request().get("/some").then()
           .statusCode(200)
           .extract()
           .body().asString();
  }
}

What I'd like to do now is to "pre-configure" the specifications to preserve cookies between the requests. I am feeding the list of cookies to send using RequestSpecification.cookies(Cookies) , but I can't find any way to instruct the specifications to extract the returned cookies before obtaining the instance of Response . However, such instance is only available after calling one of the RequestSender methods, which I can't do in the base code.

The methods I've considered to solve this are outlined below, but the first two are quite clunky, and the third is probably just outright wrong as it meddles with classes in "internal" sub-packages. Is there a "right" way of doing this?

  1. Add a base method saveCookies() that takes in an instance of ValidatableResponse , on which it can call extract() , and get the cookies. Then each test will have to use the method.
public abstract class TestBase
  // ...
  protected ValidatableResponse saveCookies(ValidatableResponse r) {
    saveGlobalCookies(r.extract().detailedCookies());
    return r;
  }
}
public class ActualTest extends TestBase {
  @Test
  public void test1() {
    String content = saveCookies(request().get("/some").then())
           .statusCode(200)
           .extract()
           .body().asString();
  }
}
  1. Use a base method that takes in lambdas so that the potentially intermediate ValidatableResponse can be intercepted, and the final result (if needed) returned to the invoker.
public abstract class TestBase
  // ...
  <T> T cookieRequest(Function<RequestSender, ValidatableResponse> exec, Function<ValidatableResponse, T> post) {

        ValidatableResponse vr = exec.apply(request());
        saveGlobalCookies(vr.extract().detailedCookies());
        return post.apply(vr);

    }
}
public class ActualTest extends TestBase {
  @Test
  public void test1() {
    String content = cookieRequest(r->r.get("/some").then(),
       r->r.extract().body().asString());
  }
}
  1. Instantiate extended instances of ResponseSpecificationImpl (dragging in RequestSpecificationImpl and TestSpecificationImpl ).

You can use CookieFilter to satify your need.

The cookie filter can be used to keep track of all the cookies sent by the server and use them in subsequent requests

You can use this class in 2 ways:

  1. Static setting:
RestAssured.filters(new CookieFilter());
  1. Specify for request you want:
CookieFilter cookieFilter = new CookieFilter();

//Request 1  
given().filter(cookieFilter).get("/x");

//Request 2
given().filter(cookieFilter).get("/y");

For more information:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM