djangid / rest-assured

Automatically exported from code.google.com/p/rest-assured
0 stars 0 forks source link

Add support for assertions #44

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
E.g. 

given().
        param(x, y).
when().
        get("/lotto").
then(). 
        assertThat("lotto.lottoId", is(5));

Copy assertThat defs from JUnit. 

get("/lotto") returns an AssertableResponse class which extends Response and 
adds assertion capabilities.

Original issue reported on code.google.com by johan.ha...@gmail.com on 15 Mar 2011 at 12:23

GoogleCodeExporter commented 8 years ago
assertThat: Have a look at MatcherAssert in Hamcrest

Original comment by johan.ha...@gmail.com on 23 Mar 2011 at 8:35

GoogleCodeExporter commented 8 years ago

Original comment by johan.ha...@gmail.com on 22 May 2011 at 8:45

GoogleCodeExporter commented 8 years ago

Original comment by johan.ha...@gmail.com on 3 Oct 2011 at 5:24

GoogleCodeExporter commented 8 years ago

Original comment by johan.ha...@gmail.com on 2 Nov 2011 at 8:17

GoogleCodeExporter commented 8 years ago
Should probably be:

given().
        param(x, y).
when().
        get("/lotto").
then(). 
        body("lotto.lottoId", is(5));

Original comment by johan.ha...@gmail.com on 19 Jan 2012 at 8:52

GoogleCodeExporter commented 8 years ago
I love and use this library, but one complaint I have about the API is that the 
current "body" method is a little bit "too smart" in the matchers that it 
accepts.  Notably, I ran into a bug where body() would take a HaxXPath matcher 
just fine, but would completely fail on an Matchers.allOf(HasXPath1, 
HasXPath2).  That's because body() accepts all kinds of matchers and tries to 
tailor its output to the type it was given. This breaks generics and the 
principle of least surprise.

It'd be pretty hard to fix this in the existing DSL without breaking backwards 
compatibility.  Is it possible that we leverage this addition to have cleaner 
assertions?  I would suggest separate assertion methods (one that takes a 
Matcher<? super Node>, one that takes a Matcher<? super String>, etc.)  

Original comment by markpete...@gmail.com on 29 Apr 2012 at 3:05

GoogleCodeExporter commented 8 years ago
Thanks for your feedback. Can you given me an example of when it fails?

Regards,
/Johan

Original comment by johan.ha...@gmail.com on 30 Apr 2012 at 11:31

GoogleCodeExporter commented 8 years ago
Hi Johan, here's a more full example.  Dependencies are JUnit 4.8.1, 
Hamcrest-library 1.3.RC2, Rest-Assured 1.6.1.

@Test
public void testXPathMatchers() {
   RestAssured.baseURI = "http://news.ycombinator.com";
   RestAssured.port = 80;

   //works
   RestAssured.given().expect()
        .body(Matchers.hasXPath("/rss/channel/title"))
        .when().get("/rss");

   //works
   RestAssured.given().expect()
        .body(Matchers.hasXPath("/rss/channel/description"))
        .when().get("/rss");

   //doesn't work
   RestAssured.given().expect()
        .body(Matchers.anyOf(
                Matchers.hasXPath("/rss/channel/title"),
                Matchers.hasXPath("/rss/channel/description")
        ))
        .when().get("/rss");
}

When I was diagnosing the issue, I tracked it down to BodyMatcher.isFulfilled() 
line 35:

if(isXPathMatcher()) {
        Element node = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new ByteArrayInputStream(response.asByteArray())).getDocumentElement();
        if (matcher.matches(node) == false) {
          throw new AssertionError(String.format("Body doesn't match.\nExpected:\n%s\nActual:\n%s", matcher.toString(), content))
        }
      }

Since isXPathMatcher() just checks whether the matcher is an instance of 
HasXPath, this will fail (as Matchers.anyOf is generic and is not a HasXPath).  
My workaround was to explicitly do the transform inlined:

...().expect()
    .body(asXmlNode(anyOf(hasXPath(...), hasXPath(...))))

Where asXmlNode essentially does the same thing as above to get a Node and then 
passes it to its matcher.  I'm suggesting we either do that (making the as* 
methods utility methods) or add assertions like

given().
        param(x, y).
when().
        get("/lotto").
assert(). 
        bodyAsXml(hasXPath(...)).
        bodyAsJson(...)

(with potentially better names).  bodyAsXml() would accept a Matcher<? super 
Node> so that it's type safe again.

The main complaint (given that I did implement a workaround) was just how it 
violates the principle of least surprise.  You get to the point of expecting to 
be able to pass in a Matcher<Node> (since it has accepted all my Matcher<Node> 
up to that point) and then it fails.

Thanks for the consideration.  Let me know if this has been talked about 
before, or if I should be directing this suggestion somewhere else.  I didn't 
file an issue against 1.x to start with because I can imagine it would be 
difficult to modify the DSL at this point (unless we only add methods?).

Original comment by markpete...@gmail.com on 30 Apr 2012 at 1:56

GoogleCodeExporter commented 8 years ago
Issue 241 has been merged into this issue.

Original comment by johan.ha...@gmail.com on 3 Jun 2013 at 6:49

GoogleCodeExporter commented 8 years ago
Issue 241 has been merged into this issue.

Original comment by johan.ha...@gmail.com on 3 Jun 2013 at 8:26

GoogleCodeExporter commented 8 years ago
Issue 241 has been merged into this issue.

Original comment by johan.ha...@gmail.com on 3 Jun 2013 at 8:33

GoogleCodeExporter commented 8 years ago
Implemented in 2.0

Original comment by johan.ha...@gmail.com on 5 Dec 2013 at 7:38