Browse Source

Introduce additional JsonPath RequestMatchers in Spring MVC Test

Commit fffdd1e9e9 introduced additional
JsonPath result matchers in JsonPathResultMatchers for server-side
testing of MVC controllers.

This commit introduces comparable methods in JsonPathRequestMatchers
for client-side testing with a RestTemplate.

- isString()
- isBoolean()
- isNumber()
- isMap()

Issue: SPR-13320
pull/858/head
Sam Brannen 11 years ago
parent
commit
4799668a98
  1. 56
      spring-test/src/main/java/org/springframework/test/web/client/match/JsonPathRequestMatchers.java
  2. 45
      spring-test/src/test/java/org/springframework/test/web/client/match/JsonPathRequestMatchersTests.java
  3. 103
      spring-test/src/test/java/org/springframework/test/web/client/samples/matchers/JsonPathRequestMatchersIntegrationTests.java

56
spring-test/src/main/java/org/springframework/test/web/client/match/JsonPathRequestMatchers.java

@ -115,6 +115,48 @@ public class JsonPathRequestMatchers { @@ -115,6 +115,48 @@ public class JsonPathRequestMatchers {
};
}
/**
* Evaluate the JSON path expression against the request content and
* assert that the result is a {@link String}.
* @since 4.2.1
*/
public RequestMatcher isString() {
return new AbstractJsonPathRequestMatcher() {
@Override
public void matchInternal(MockClientHttpRequest request) throws IOException, ParseException {
JsonPathRequestMatchers.this.jsonPathHelper.assertValueIsString(request.getBodyAsString());
}
};
}
/**
* Evaluate the JSON path expression against the request content and
* assert that the result is a {@link Boolean}.
* @since 4.2.1
*/
public RequestMatcher isBoolean() {
return new AbstractJsonPathRequestMatcher() {
@Override
public void matchInternal(MockClientHttpRequest request) throws IOException, ParseException {
JsonPathRequestMatchers.this.jsonPathHelper.assertValueIsBoolean(request.getBodyAsString());
}
};
}
/**
* Evaluate the JSON path expression against the request content and
* assert that the result is a {@link Number}.
* @since 4.2.1
*/
public RequestMatcher isNumber() {
return new AbstractJsonPathRequestMatcher() {
@Override
public void matchInternal(MockClientHttpRequest request) throws IOException, ParseException {
JsonPathRequestMatchers.this.jsonPathHelper.assertValueIsNumber(request.getBodyAsString());
}
};
}
/**
* Evaluate the JSON path expression against the request content and
* assert that the result is an array.
@ -128,6 +170,20 @@ public class JsonPathRequestMatchers { @@ -128,6 +170,20 @@ public class JsonPathRequestMatchers {
};
}
/**
* Evaluate the JSON path expression against the request content and
* assert that the result is a {@link java.util.Map}.
* @since 4.2.1
*/
public RequestMatcher isMap() {
return new AbstractJsonPathRequestMatcher() {
@Override
public void matchInternal(MockClientHttpRequest request) throws IOException, ParseException {
JsonPathRequestMatchers.this.jsonPathHelper.assertValueIsMap(request.getBodyAsString());
}
};
}
/**
* Abstract base class for {@code JsonPath}-based {@link RequestMatcher}s.

45
spring-test/src/test/java/org/springframework/test/web/client/match/JsonPathRequestMatchersTests.java

@ -129,4 +129,49 @@ public class JsonPathRequestMatchersTests { @@ -129,4 +129,49 @@ public class JsonPathRequestMatchersTests {
new JsonPathRequestMatchers("$.str").isArray().match(request);
}
@Test
public void isMap() throws Exception {
new JsonPathRequestMatchers("$.colorMap").isMap().match(request);
}
@Test
public void isMapForAnEmptyMap() throws Exception {
new JsonPathRequestMatchers("$.emptyMap").isMap().match(request);
}
@Test(expected = AssertionError.class)
public void isMapNoMatch() throws Exception {
new JsonPathRequestMatchers("$.str").isMap().match(request);
}
@Test
public void isBoolean() throws Exception {
new JsonPathRequestMatchers("$.bool").isBoolean().match(request);
}
@Test(expected = AssertionError.class)
public void isBooleanNoMatch() throws Exception {
new JsonPathRequestMatchers("$.str").isBoolean().match(request);
}
@Test
public void isNumber() throws Exception {
new JsonPathRequestMatchers("$.num").isNumber().match(request);
}
@Test(expected = AssertionError.class)
public void isNumberNoMatch() throws Exception {
new JsonPathRequestMatchers("$.str").isNumber().match(request);
}
@Test
public void isString() throws Exception {
new JsonPathRequestMatchers("$.str").isString().match(request);
}
@Test(expected = AssertionError.class)
public void isStringNoMatch() throws Exception {
new JsonPathRequestMatchers("$.arr").isString().match(request);
}
}

103
spring-test/src/test/java/org/springframework/test/web/client/samples/matchers/JsonPathRequestMatchersIntegrationTests.java

@ -17,14 +17,12 @@ @@ -17,14 +17,12 @@
package org.springframework.test.web.client.samples.matchers;
import java.net.URI;
import java.util.ArrayList;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.List;
import org.junit.Before;
import org.junit.After;
import org.junit.Test;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.test.web.Person;
import org.springframework.test.web.client.MockRestServiceServer;
@ -41,38 +39,30 @@ import static org.springframework.test.web.client.response.MockRestResponseCreat @@ -41,38 +39,30 @@ import static org.springframework.test.web.client.response.MockRestResponseCreat
* <a href="https://github.com/jayway/JsonPath">JsonPath</a> expressions.
*
* @author Rossen Stoyanchev
* @author Sam Brannen
* @see org.springframework.test.web.client.match.JsonPathRequestMatchers
* @see org.springframework.test.web.client.match.JsonPathRequestMatchersTests
*/
public class JsonPathRequestMatchersIntegrationTests {
private MockRestServiceServer mockServer;
private static final MultiValueMap<String, Person> people = new LinkedMultiValueMap<String, Person>();
private RestTemplate restTemplate;
private MultiValueMap<String, Person> people;
@Before
public void setup() {
this.people = new LinkedMultiValueMap<String, Person>();
this.people.add("composers", new Person("Johann Sebastian Bach"));
this.people.add("composers", new Person("Johannes Brahms"));
this.people.add("composers", new Person("Edvard Grieg"));
this.people.add("composers", new Person("Robert Schumann"));
this.people.add("performers", new Person("Vladimir Ashkenazy"));
this.people.add("performers", new Person("Yehudi Menuhin"));
static {
people.add("composers", new Person("Johann Sebastian Bach"));
people.add("composers", new Person("Johannes Brahms"));
people.add("composers", new Person("Edvard Grieg"));
people.add("composers", new Person("Robert Schumann"));
people.add("performers", new Person("Vladimir Ashkenazy"));
people.add("performers", new Person("Yehudi Menuhin"));
}
List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
converters.add(new MappingJackson2HttpMessageConverter());
private final RestTemplate restTemplate = new RestTemplate(Arrays.asList(new MappingJackson2HttpMessageConverter()));
this.restTemplate = new RestTemplate();
this.restTemplate.setMessageConverters(converters);
private final MockRestServiceServer mockServer = MockRestServiceServer.createServer(this.restTemplate);
this.mockServer = MockRestServiceServer.createServer(this.restTemplate);
}
@Test
public void testExists() throws Exception {
public void exists() throws Exception {
this.mockServer.expect(requestTo("/composers"))
.andExpect(content().contentType("application/json;charset=UTF-8"))
.andExpect(jsonPath("$.composers[0]").exists())
@ -80,13 +70,10 @@ public class JsonPathRequestMatchersIntegrationTests { @@ -80,13 +70,10 @@ public class JsonPathRequestMatchersIntegrationTests {
.andExpect(jsonPath("$.composers[2]").exists())
.andExpect(jsonPath("$.composers[3]").exists())
.andRespond(withSuccess());
this.restTemplate.put(new URI("/composers"), this.people);
this.mockServer.verify();
}
@Test
public void testDoesNotExist() throws Exception {
public void doesNotExist() throws Exception {
this.mockServer.expect(requestTo("/composers"))
.andExpect(content().contentType("application/json;charset=UTF-8"))
.andExpect(jsonPath("$.composers[?(@.name == 'Edvard Grieeeeeeg')]").doesNotExist())
@ -94,42 +81,33 @@ public class JsonPathRequestMatchersIntegrationTests { @@ -94,42 +81,33 @@ public class JsonPathRequestMatchersIntegrationTests {
.andExpect(jsonPath("$.composers[-1]").doesNotExist())
.andExpect(jsonPath("$.composers[4]").doesNotExist())
.andRespond(withSuccess());
this.restTemplate.put(new URI("/composers"), this.people);
this.mockServer.verify();
}
@Test
public void testEqualTo() throws Exception {
public void value() throws Exception {
this.mockServer.expect(requestTo("/composers"))
.andExpect(content().contentType("application/json;charset=UTF-8"))
.andExpect(jsonPath("$.composers[0].name").value("Johann Sebastian Bach"))
.andExpect(jsonPath("$.performers[1].name").value("Yehudi Menuhin"))
.andExpect(jsonPath("$.composers[0].name").value(equalTo("Johann Sebastian Bach"))) // Hamcrest
.andExpect(jsonPath("$.performers[1].name").value(equalTo("Yehudi Menuhin"))) // Hamcrest
.andRespond(withSuccess());
this.restTemplate.put(new URI("/composers"), this.people);
this.mockServer.verify();
}
@Test
public void testHamcrestMatcher() throws Exception {
public void hamcrestMatchers() throws Exception {
this.mockServer.expect(requestTo("/composers"))
.andExpect(content().contentType("application/json;charset=UTF-8"))
.andExpect(jsonPath("$.composers[0].name").value(equalTo("Johann Sebastian Bach")))
.andExpect(jsonPath("$.performers[1].name").value(equalTo("Yehudi Menuhin")))
.andExpect(jsonPath("$.composers[0].name", startsWith("Johann")))
.andExpect(jsonPath("$.performers[0].name", endsWith("Ashkenazy")))
.andExpect(jsonPath("$.performers[1].name", containsString("di Me")))
.andExpect(jsonPath("$.composers[1].name", isIn(Arrays.asList("Johann Sebastian Bach", "Johannes Brahms"))))
.andExpect(jsonPath("$.composers[:3].name", hasItem("Johannes Brahms")))
.andRespond(withSuccess());
this.restTemplate.put(new URI("/composers"), this.people);
this.mockServer.verify();
}
@Test
public void testHamcrestMatcherWithParameterizedJsonPath() throws Exception {
public void hamcrestMatchersWithParameterizedJsonPaths() throws Exception {
String composerName = "$.composers[%s].name";
String performerName = "$.performers[%s].name";
@ -140,8 +118,43 @@ public class JsonPathRequestMatchersIntegrationTests { @@ -140,8 +118,43 @@ public class JsonPathRequestMatchersIntegrationTests {
.andExpect(jsonPath(performerName, 1).value(containsString("di Me")))
.andExpect(jsonPath(composerName, 1).value(isIn(Arrays.asList("Johann Sebastian Bach", "Johannes Brahms"))))
.andRespond(withSuccess());
}
@Test
public void isArray() throws Exception {
this.mockServer.expect(requestTo("/composers"))
.andExpect(content().contentType("application/json;charset=UTF-8"))
.andExpect(jsonPath("$.composers").isArray())
.andRespond(withSuccess());
}
@Test
public void isString() throws Exception {
this.mockServer.expect(requestTo("/composers"))
.andExpect(content().contentType("application/json;charset=UTF-8"))
.andExpect(jsonPath("$.composers[0].name").isString())
.andRespond(withSuccess());
}
@Test
public void isNumber() throws Exception {
this.mockServer.expect(requestTo("/composers"))
.andExpect(content().contentType("application/json;charset=UTF-8"))
.andExpect(jsonPath("$.composers[0].someDouble").isNumber())
.andRespond(withSuccess());
}
@Test
public void isBoolean() throws Exception {
this.mockServer.expect(requestTo("/composers"))
.andExpect(content().contentType("application/json;charset=UTF-8"))
.andExpect(jsonPath("$.composers[0].someBoolean").isBoolean())
.andRespond(withSuccess());
}
this.restTemplate.put(new URI("/composers"), this.people);
@After
public void performRequestAndVerify() throws URISyntaxException {
this.restTemplate.put(new URI("/composers"), people);
this.mockServer.verify();
}

Loading…
Cancel
Save