diff --git a/rest/security/pom.xml b/rest/security/pom.xml
index 897ff186..ef2602cc 100644
--- a/rest/security/pom.xml
+++ b/rest/security/pom.xml
@@ -34,17 +34,13 @@
hsqldb
-
- org.springframework.boot
- spring-boot-starter-test
- te
-
-
-
- org.projectlombok
- lombok
-
-
+
+
+
+ spring-libs-snapshot
+ https://repo.spring.io/libs-snapshot
+
+
diff --git a/rest/security/src/main/java/example/company/Application.java b/rest/security/src/main/java/example/company/Application.java
index 23499ed4..aecf8448 100644
--- a/rest/security/src/main/java/example/company/Application.java
+++ b/rest/security/src/main/java/example/company/Application.java
@@ -60,5 +60,4 @@ public class Application {
SecurityContextHolder.clearContext();
}
-
}
diff --git a/rest/security/src/main/java/example/company/Employee.java b/rest/security/src/main/java/example/company/Employee.java
index 40b4bc9b..ddae188f 100644
--- a/rest/security/src/main/java/example/company/Employee.java
+++ b/rest/security/src/main/java/example/company/Employee.java
@@ -19,29 +19,28 @@ import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import lombok.RequiredArgsConstructor;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
/**
* Domain object for an employee.
*
* @author Greg Turnquist
*/
-@Entity
-@JsonIgnoreProperties(ignoreUnknown = true)
@Data
+@Entity
@RequiredArgsConstructor
+@JsonIgnoreProperties(ignoreUnknown = true)
public class Employee {
- @Id @GeneratedValue private Long id;
+ private @Id @GeneratedValue Long id;
private final String firstName, lastName, title;
Employee() {
-
this.firstName = null;
this.lastName = null;
this.title = null;
}
-
}
diff --git a/rest/security/src/main/java/example/company/EmployeeRepository.java b/rest/security/src/main/java/example/company/EmployeeRepository.java
index ab4bb812..580274b8 100644
--- a/rest/security/src/main/java/example/company/EmployeeRepository.java
+++ b/rest/security/src/main/java/example/company/EmployeeRepository.java
@@ -23,6 +23,4 @@ import org.springframework.data.repository.CrudRepository;
*
* @author Greg Turnquist
*/
-public interface EmployeeRepository extends CrudRepository {
-
-}
+public interface EmployeeRepository extends CrudRepository {}
diff --git a/rest/security/src/main/java/example/company/Item.java b/rest/security/src/main/java/example/company/Item.java
index 28cb0e72..f08d4446 100644
--- a/rest/security/src/main/java/example/company/Item.java
+++ b/rest/security/src/main/java/example/company/Item.java
@@ -26,18 +26,17 @@ import lombok.RequiredArgsConstructor;
* Domain object for an item managed by the company.
*
* @author Greg Turnquist
+ * @author Oliver Gierke
*/
@Entity
@Data
@RequiredArgsConstructor
public class Item {
- @Id @GeneratedValue private Long id;
-
+ private @Id @GeneratedValue Long id;
private final String description;
Item() {
this.description = null;
}
-
}
diff --git a/rest/security/src/main/java/example/company/ItemRepository.java b/rest/security/src/main/java/example/company/ItemRepository.java
index d019b8a7..db12c9ce 100644
--- a/rest/security/src/main/java/example/company/ItemRepository.java
+++ b/rest/security/src/main/java/example/company/ItemRepository.java
@@ -23,15 +23,24 @@ import org.springframework.security.access.prepost.PreAuthorize;
* operations require ROLE_ADMIN.
*
* @author Greg Turnquist
+ * @author Oliver Gierke
*/
@PreAuthorize("hasRole('ROLE_USER')")
public interface ItemRepository extends CrudRepository- {
- @PreAuthorize("hasRole('ROLE_ADMIN')")
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.repository.CrudRepository#save(S)
+ */
@Override
- Item save(Item s);
+ @PreAuthorize("hasRole('ROLE_ADMIN')")
+
S save(S s);
- @PreAuthorize("hasRole('ROLE_ADMIN')")
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.repository.CrudRepository#delete(java.io.Serializable)
+ */
@Override
+ @PreAuthorize("hasRole('ROLE_ADMIN')")
void delete(Long aLong);
}
diff --git a/rest/security/src/main/java/example/company/SecurityConfiguration.java b/rest/security/src/main/java/example/company/SecurityConfiguration.java
index c311b395..0b4b8351 100644
--- a/rest/security/src/main/java/example/company/SecurityConfiguration.java
+++ b/rest/security/src/main/java/example/company/SecurityConfiguration.java
@@ -15,7 +15,6 @@
*/
package example.company;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
@@ -26,10 +25,10 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
/**
* This application is secured at both the URL level for some parts, and the method level for other parts. The URL
* security is shown inside this code, while method-level annotations are enabled at by
- * {@link org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity
- * EnableGlobalMethodSecurity}
+ * {@link EnableGlobalMethodSecurity}.
*
* @author Greg Turnquist
+ * @author Oliver Gierke
*/
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@@ -37,35 +36,38 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
/**
* This section defines the user accounts which can be used for authentication as well as the roles each user has.
- *
- * @param auth
- * @throws Exception
+ *
+ * @see org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter#configure(org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder)
*/
- @Autowired
- public void configureAuth(AuthenticationManagerBuilder auth) throws Exception {
- auth.inMemoryAuthentication()
- .withUser("greg").password("turnquist").roles("USER").and()
- .withUser("ollie").password("gierke").roles("USER", "ADMIN");
+ @Override
+ protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+
+ auth.inMemoryAuthentication().//
+ withUser("greg").password("turnquist").roles("USER").and().//
+ withUser("ollie").password("gierke").roles("USER", "ADMIN");
}
/**
- * This section defines the security policy for the app. - BASIC authentication is supported (enough for this
- * REST-based demo) - /employees is secured using URL security shown below - CSRF headers are disabled since we are
- * only testing the REST interface, not a web one. NOTE: GET is not shown which defaults to permitted.
+ * This section defines the security policy for the app.
+ *
+ *
+ * - BASIC authentication is supported (enough for this REST-based demo).
+ * - /employees is secured using URL security shown below.
+ * - CSRF headers are disabled since we are only testing the REST interface, not a web one.
+ *
+ * NOTE: GET is not shown which defaults to permitted.
*
* @param http
* @throws Exception
+ * @see org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter#configure(org.springframework.security.config.annotation.web.builders.HttpSecurity)
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
- http
- .httpBasic()
- .and()
- .authorizeRequests()
- .antMatchers(HttpMethod.POST, "/employees").hasRole("ADMIN")
- .antMatchers(HttpMethod.PUT, "/employees/**").hasRole("ADMIN")
- .antMatchers(HttpMethod.PATCH, "/employees/**").hasRole("ADMIN")
- .and()
- .csrf().disable();
+
+ http.httpBasic().and().authorizeRequests().//
+ antMatchers(HttpMethod.POST, "/employees").hasRole("ADMIN").//
+ antMatchers(HttpMethod.PUT, "/employees/**").hasRole("ADMIN").//
+ antMatchers(HttpMethod.PATCH, "/employees/**").hasRole("ADMIN").and().//
+ csrf().disable();
}
}
diff --git a/rest/security/src/main/java/example/company/SecurityUtils.java b/rest/security/src/main/java/example/company/SecurityUtils.java
index 61bfcfa0..c1fb64b0 100644
--- a/rest/security/src/main/java/example/company/SecurityUtils.java
+++ b/rest/security/src/main/java/example/company/SecurityUtils.java
@@ -17,18 +17,32 @@ package example.company;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.AuthorityUtils;
+import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.util.Assert;
/**
* Some convenient security utilities.
*
* @author Greg Turnquist
+ * @author Oliver Gierke
*/
-public class SecurityUtils {
+class SecurityUtils {
+ /**
+ * Configures the Spring Security {@link SecurityContext} to be authenticated as the user with the given username and
+ * password as well as the given granted authorities.
+ *
+ * @param username must not be {@literal null} or empty.
+ * @param password must not be {@literal null} or empty.
+ * @param roles
+ */
public static void runAs(String username, String password, String... roles) {
+ Assert.notNull(username, "Username must not be null!");
+ Assert.notNull(password, "Password must not be null!");
+
SecurityContextHolder.getContext().setAuthentication(
- new UsernamePasswordAuthenticationToken(username, password, AuthorityUtils.createAuthorityList(roles)));
+ new UsernamePasswordAuthenticationToken(username, password, AuthorityUtils.createAuthorityList(roles)));
}
}
diff --git a/rest/security/src/test/java/example/company/MethodLevelSecurityTests.java b/rest/security/src/test/java/example/company/MethodLevelSecurityTests.java
index b3462bb9..d5df2c0e 100644
--- a/rest/security/src/test/java/example/company/MethodLevelSecurityTests.java
+++ b/rest/security/src/test/java/example/company/MethodLevelSecurityTests.java
@@ -1,80 +1,53 @@
+/*
+ * Copyright 2014 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package example.company;
-import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
-import org.springframework.http.HttpEntity;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpMethod;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.crypto.codec.Base64;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
-import org.springframework.util.MultiValueMap;
-import org.springframework.web.client.RestTemplate;
-
-import com.fasterxml.jackson.databind.JsonNode;
/**
* Collection of test cases used to verify method-level security.
*
* @author Greg Turnquist
+ * @author Oliver Gierke
*/
@RunWith(SpringJUnit4ClassRunner.class)
-@SpringApplicationConfiguration(classes = { Application.class, SecurityConfiguration.class })
@WebAppConfiguration
-@IntegrationTest("server.port:0")
+@SpringApplicationConfiguration(classes = { Application.class, SecurityConfiguration.class })
public class MethodLevelSecurityTests {
- private String baseUrl;
-
- @Value("${local.server.port}")
- private int port;
-
- @Autowired
- ItemRepository itemRepository;
+ @Autowired ItemRepository itemRepository;
@Before
public void setUp() {
-
- this.baseUrl = "http://localhost:" + port;
SecurityContextHolder.clearContext();
}
@Test
- public void testMethodLevelSecurityForNoCreds() {
-
- HttpHeaders headers = new HttpHeaders();
- headers.set("Accept", "application/hal+json");
- String creds = new String(Base64.encode(("greg:turnquist").getBytes()));
- headers.set("Authorization", "Basic " + creds);
-
- RestTemplate rest = new RestTemplate();
- HttpEntity> request = new HttpEntity<>(null, headers);
-
- System.out.println("============= GET " + baseUrl + "/items");
-
- System.out.println(SecurityContextHolder.getContext().getAuthentication());
-
- ResponseEntity itemsResponse = rest.exchange(baseUrl + "/items", HttpMethod.GET, request, JsonNode.class);
- itemsResponse.getHeaders().entrySet().stream()
- .map(e -> e.getKey() + ": " + e.getValue())
- .forEach(header -> System.out.println(header));
- assertThat(itemsResponse.getHeaders().get("Content-Type"), hasItems("application/hal+json"));
- assertThat(itemsResponse.getStatusCode(), equalTo(HttpStatus.OK));
- System.out.println();
- System.out.println(itemsResponse.getBody());
+ public void rejectsMethodInvocationsForNoAuth() {
try {
itemRepository.findAll();
@@ -99,7 +72,7 @@ public class MethodLevelSecurityTests {
}
@Test
- public void testMethodLevelSecurityForUsers() {
+ public void rejectsMethodInvocationsForAuthWithInsufficientPermissions() {
SecurityUtils.runAs("system", "system", "ROLE_USER");
@@ -120,7 +93,7 @@ public class MethodLevelSecurityTests {
}
@Test
- public void testMethodLevelSecurityForAdmins() {
+ public void allowsMethodInvocationsForAuthWithSufficientPermissions() {
SecurityUtils.runAs("system", "system", "ROLE_USER", "ROLE_ADMIN");
diff --git a/rest/security/src/test/java/example/company/UrlLevelSecurityTests.java b/rest/security/src/test/java/example/company/UrlLevelSecurityTests.java
index 0c424b74..d284f967 100644
--- a/rest/security/src/test/java/example/company/UrlLevelSecurityTests.java
+++ b/rest/security/src/test/java/example/company/UrlLevelSecurityTests.java
@@ -17,164 +17,124 @@ package example.company;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+import static org.springframework.test.web.servlet.setup.MockMvcBuilders.*;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.test.IntegrationTest;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
-import org.springframework.http.HttpEntity;
+import org.springframework.hateoas.MediaTypes;
import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpMethod;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
+import org.springframework.http.MediaType;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.codec.Base64;
+import org.springframework.security.web.FilterChainProxy;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
-import org.springframework.util.MultiValueMap;
-import org.springframework.web.client.HttpClientErrorException;
-import org.springframework.web.client.RestTemplate;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.web.context.WebApplicationContext;
-import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
/**
- * Test cases that verify the URL level of security by using RestTemplate.
+ * Test cases that verify the URL level of security by using the Spring MVC test framework.
*
* @author Greg Turnquist
+ * @author Oliver Gierke
*/
@RunWith(SpringJUnit4ClassRunner.class)
-@SpringApplicationConfiguration(classes = { Application.class, SecurityConfiguration.class })
@WebAppConfiguration
-@IntegrationTest("server.port:0")
+@SpringApplicationConfiguration(classes = { Application.class, SecurityConfiguration.class })
public class UrlLevelSecurityTests {
- private String baseUrl;
+ static final String PAYLOAD = "{\"firstName\": \"Saruman\", \"lastName\": \"the White\", " + "\"title\": \"Wizard\"}";
- @Value("${local.server.port}") private int port;
+ @Autowired WebApplicationContext context;
+ @Autowired FilterChainProxy filterChain;
+
+ MockMvc mvc;
@Before
public void setUp() {
- this.baseUrl = "http://localhost:" + port;
+ this.mvc = webAppContextSetup(context).addFilters(filterChain).build();
+
SecurityContextHolder.clearContext();
}
@Test
- public void testUrlSecurityForNoCreds() {
+ public void allowsAccessToRootResource() throws Exception {
- HttpHeaders headers = new HttpHeaders();
- headers.set("Accept", "application/hal+json");
-
- HttpEntity> baseRequest = new HttpEntity<>(headers);
-
- RestTemplate rest = new RestTemplate();
-
- System.out.println("============= GET " + baseUrl);
-
- ResponseEntity baseResponse = rest.exchange(baseUrl, HttpMethod.GET, baseRequest, JsonNode.class);
- baseResponse.getHeaders().entrySet().stream()//
- .map(e -> e.getKey() + ": " + e.getValue())//
- .forEach(header -> System.out.println(header));
- assertThat(baseResponse.getHeaders().get("Content-Type"), hasItems("application/hal+json"));
- assertThat(baseResponse.getStatusCode(), equalTo(HttpStatus.OK));
- System.out.println();
- System.out.println(baseResponse.getBody());
-
- System.out.println("============= POST " + baseUrl + "/employees");
-
- HttpEntity newEmployee = new HttpEntity<>("{firstName: Saruman, lastName: the White, title: Wizard}",
- headers);
-
- try {
- rest.exchange(baseUrl + "/employees", HttpMethod.POST, newEmployee, JsonNode.class);
- fail("Expected a security error");
- } catch (HttpClientErrorException e) {
- assertThat(e.getStatusCode(), equalTo(HttpStatus.UNAUTHORIZED));
- }
+ mvc.perform(get("/").//
+ accept(MediaTypes.HAL_JSON)).//
+ andExpect(header().string("Content-Type", MediaTypes.HAL_JSON.toString())).//
+ andExpect(status().isOk()).//
+ andDo(print());
}
@Test
- public void testUrlSecurityForUsers() {
+ public void rejectsPostAccessToCollectionResource() throws Exception {
- System.out.println("============= GET " + baseUrl + "/employees");
-
- HttpHeaders headers = new HttpHeaders();
- headers.set("Accept", "application/hal+json");
-
- String userCreds = new String(Base64.encode(("greg:turnquist").getBytes()));
- headers.set("Authorization", "Basic " + userCreds);
- headers.set("Accept", "application/hal+json");
-
- HttpEntity> request = new HttpEntity<>(headers);
-
- RestTemplate rest = new RestTemplate();
-
- ResponseEntity employeesResponse = rest.exchange(baseUrl + "/employees", HttpMethod.GET, request,
- JsonNode.class);
- employeesResponse.getHeaders().entrySet().stream()//
- .map(e -> e.getKey() + ": " + e.getValue())//
- .forEach(header -> System.out.println(header));
- assertThat(employeesResponse.getHeaders().get("Content-Type"), hasItems("application/hal+json"));
- assertThat(employeesResponse.getStatusCode(), equalTo(HttpStatus.OK));
- System.out.println();
- System.out.println(employeesResponse.getBody());
-
- System.out.println("============= POST " + baseUrl + "/employees");
-
- HttpEntity newEmployee = new HttpEntity<>("{\"firstName\": \"Saruman\", " + "\"lastName\": \"the White\", "
- + "\"title\": \"Wizard\"}", headers);
-
- try {
- rest.exchange(baseUrl + "/employees", HttpMethod.POST, newEmployee, JsonNode.class);
- fail("Expected a security error");
- } catch (HttpClientErrorException e) {
- assertThat(e.getStatusCode(), equalTo(HttpStatus.FORBIDDEN));
- }
+ mvc.perform(post("/employees").//
+ content(PAYLOAD).//
+ accept(MediaTypes.HAL_JSON)).//
+ andExpect(status().isUnauthorized()).//
+ andDo(print());
}
@Test
- public void testUrlSecurityForAdmins() {
-
- System.out.println("============= GET " + baseUrl + "/employees");
+ public void allowsGetRequestsButRejectsPostForUser() throws Exception {
HttpHeaders headers = new HttpHeaders();
- headers.set("Accept", "application/hal+json");
+ headers.add(HttpHeaders.ACCEPT, MediaTypes.HAL_JSON.toString());
+ headers.add(HttpHeaders.AUTHORIZATION, "Basic " + new String(Base64.encode(("greg:turnquist").getBytes())));
- String userCreds = new String(Base64.encode(("ollie:gierke").getBytes()));
- headers.set("Authorization", "Basic " + userCreds);
- headers.set("Accept", "application/hal+json");
+ mvc.perform(get("/employees").//
+ headers(headers)).//
+ andExpect(content().contentType(MediaTypes.HAL_JSON)).//
+ andExpect(status().isOk()).//
+ andDo(print());
- HttpEntity> request = new HttpEntity<>(headers);
+ mvc.perform(post("/employees").//
+ headers(headers)).//
+ andExpect(status().isForbidden()).//
+ andDo(print());
+ }
- RestTemplate rest = new RestTemplate();
+ @Test
+ public void allowsPostRequestForAdmin() throws Exception {
- ResponseEntity employeesResponse = rest.exchange(baseUrl + "/employees", HttpMethod.GET, request,
- JsonNode.class);
- employeesResponse.getHeaders().entrySet().stream()//
- .map(e -> e.getKey() + ": " + e.getValue())//
- .forEach(header -> System.out.println(header));
- assertThat(employeesResponse.getHeaders().get("Content-Type"), hasItems("application/hal+json"));
- assertThat(employeesResponse.getStatusCode(), equalTo(HttpStatus.OK));
- System.out.println();
- System.out.println(employeesResponse.getBody());
+ HttpHeaders headers = new HttpHeaders();
+ headers.set(HttpHeaders.ACCEPT, "application/hal+json");
+ headers.set(HttpHeaders.AUTHORIZATION, "Basic " + new String(Base64.encode(("ollie:gierke").getBytes())));
- System.out.println("============= POST " + baseUrl + "/employees");
+ mvc.perform(get("/employees").//
+ headers(headers)).//
+ andExpect(content().contentType(MediaTypes.HAL_JSON)).//
+ andExpect(status().isOk()).//
+ andDo(print());
- headers.add("Content-Type", "application/json");
+ headers.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
- HttpEntity newEmployee = new HttpEntity<>("{\"firstName\": \"Saruman\", " + "\"lastName\": \"the White\", "
- + "\"title\": \"Wizard\"}", headers);
+ String location = mvc.perform(post("/employees").//
+ content(PAYLOAD).//
+ headers(headers)).//
+ andExpect(status().isCreated()).//
+ andDo(print()).//
+ andReturn().getResponse().getHeader(HttpHeaders.LOCATION);
- ResponseEntity response = rest.exchange(baseUrl + "/employees", HttpMethod.POST, newEmployee,
- JsonNode.class);
- assertThat(response.getStatusCode(), equalTo(HttpStatus.CREATED));
- String location = response.getHeaders().get("Location").get(0);
- Employee employee = rest.getForObject(location, Employee.class);
- assertThat(employee.getFirstName(), equalTo("Saruman"));
- assertThat(employee.getLastName(), equalTo("the White"));
- assertThat(employee.getTitle(), equalTo("Wizard"));
- System.out.println(rest.getForObject(location, String.class));
+ ObjectMapper mapper = new ObjectMapper();
+
+ String content = mvc.perform(get(location)).//
+ andReturn().getResponse().getContentAsString();
+ Employee employee = mapper.readValue(content, Employee.class);
+
+ assertThat(employee.getFirstName(), is("Saruman"));
+ assertThat(employee.getLastName(), is("the White"));
+ assertThat(employee.getTitle(), is("Wizard"));
}
}