Do more with test:
on the previous practice, we run the embed tomcat to test rest, and we don't need do that since spring provide mock mvc to simplify our test work.the older code:
/** * The test case used general resttemplate to call api and compare the response. * the whole test is running with an actual tomcat server. */package org.lz.boilerplate.springrest; import org.junit.Assert;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.boot.test.web.client.TestRestTemplate;import org.springframework.boot.web.server.LocalServerPort;import org.springframework.http.*;import org.springframework.security.oauth2.client.OAuth2RestTemplate;import org.springframework.security.oauth2.client.token.grant.password.ResourceOwnerPasswordResourceDetails;import org.springframework.test.context.junit4.SpringRunner;import org.springframework.util.LinkedMultiValueMap;import org.springframework.util.MultiValueMap; import java.util.ArrayList;import java.util.List; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class DemoAuthTests { public static final String API_DEMO_HELLO = "/api/demo/hello"; public static final String HELLO_API_EXPECTED = "helloworld"; public static final String OAUTH_END_POINT = "/oauth/token"; @LocalServerPort int randomPort; @Autowired private TestRestTemplate restTemplate; @Test public void callHelloApiFailIfNoCredential() { ResponseEntity<String> resp = this.restTemplate .exchange(API_DEMO_HELLO, HttpMethod.GET, null, String.class ); Assert.assertEquals(HttpStatus.UNAUTHORIZED, resp.getStatusCode()); } @Test public void callHelloApiOkWithBasicAuth() { ResponseEntity<String> resp = this.restTemplate.withBasicAuth("user", "password") .exchange(API_DEMO_HELLO, HttpMethod.GET, null, String.class ); Assert.assertEquals(HttpStatus.OK, resp.getStatusCode()); Assert.assertEquals(HELLO_API_EXPECTED, resp.getBody()); } @Test public void getTokenWithBasicAuth() { // $ curl <client-id> : <client-secret>@<api-end-point-url >/oauth/token // -d grant_type=password -d username=<username> -d password=< password > ResponseEntity<String> resp = this.restTemplate.withBasicAuth("lzheng-client", "lzheng-secret") .exchange(OAUTH_END_POINT, HttpMethod.POST, getOAuthFormData(), String.class); Assert.assertEquals(HttpStatus.OK, resp.getStatusCode()); Assert.assertTrue("contain access_token string", resp.getBody().contains("access_token")); } @Test public void getTokenWithoutBasicAuth() { ResponseEntity<String> resp = this.restTemplate.withBasicAuth("", "") .exchange(OAUTH_END_POINT, HttpMethod.POST, getOAuthFormData(), String.class ); Assert.assertEquals(HttpStatus.UNAUTHORIZED, resp.getStatusCode()); } @Test public void callHelooWithOAuth() { OAuth2RestTemplate template = restTemplate(); ResponseEntity<String> resp = template .exchange(covertToAbsulateUri(API_DEMO_HELLO), HttpMethod.GET, getOAuthFormData(), String.class ); Assert.assertEquals(HttpStatus.OK, resp.getStatusCode()); Assert.assertEquals(HELLO_API_EXPECTED, resp.getBody()); } private String covertToAbsulateUri(String apiDemoHello) { return "http://localhost:" + randomPort + apiDemoHello; } private HttpEntity<MultiValueMap<String, String>> getOAuthFormData() { MultiValueMap<String, String> map= new LinkedMultiValueMap<>(); map.add("grant_type", "password"); map.add("username", "user"); map.add("password", "password"); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA); return new HttpEntity<>(map, headers); } private OAuth2RestTemplate restTemplate() { ResourceOwnerPasswordResourceDetails resourceDetails = new ResourceOwnerPasswordResourceDetails(); resourceDetails.setGrantType("password"); resourceDetails.setAccessTokenUri(covertToAbsulateUri(OAUTH_END_POINT)); //-- set the clients info resourceDetails.setClientId("lzheng-client"); resourceDetails.setClientSecret("lzheng-secret"); // set scopes List<String> scopes = new ArrayList<>(); scopes.add("read"); scopes.add("write"); scopes.add("trust"); resourceDetails.setScope(scopes); resourceDetails.setUsername("user"); resourceDetails.setPassword("password"); return new OAuth2RestTemplate(resourceDetails); } }
the new code:
package org.lz.boilerplate.springrest; import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.json.JacksonJsonParser;import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.http.MediaType;import org.springframework.test.context.junit4.SpringRunner;import org.springframework.test.web.servlet.MockMvc;import org.springframework.test.web.servlet.ResultActions;import org.springframework.util.LinkedMultiValueMap;import org.springframework.util.MultiValueMap; import static org.hamcrest.core.StringContains.containsString;import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic;import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @RunWith(SpringRunner.class) @SpringBootTest@AutoConfigureMockMvcpublic class MockMvcDemoRestAPITests { public static final String API_DEMO_HELLO = "/api/demo/hello"; public static final String OAUTH_END_POINT = "/oauth/token"; public static final String HELLO_API_EXPECTED = "helloworld"; public static final String OAUTH_LZHENG_CLIENT = "lzheng-client"; public static final String OAUTH_LZHENG_SECRET = "lzheng-secret"; @Autowired private MockMvc mvc; @Test public void callHelloFailedWithNoCredential() throws Exception { this.mvc.perform(get(API_DEMO_HELLO)).andExpect(status().isUnauthorized()); } @Test public void callHelloOkWithBasicAuth() throws Exception { this.mvc.perform(get(API_DEMO_HELLO).with(httpBasic("user", "password"))) .andExpect(status().isOk()) .andExpect(content().string(HELLO_API_EXPECTED)); } @Test public void getTokenWithBasicAuth() throws Exception { this.mvc.perform(post(OAUTH_END_POINT) .contentType(MediaType.MULTIPART_FORM_DATA) .params(getOAuthFormData()) .with(httpBasic("lzheng-client", "lzheng-secret"))) .andExpect(status().isOk()) .andExpect(content().string(containsString("access_token"))); } @Test public void getTokenWithoutBasicAuth() throws Exception { this.mvc.perform(post(OAUTH_END_POINT) .with(httpBasic("", ""))) .andExpect(status().isUnauthorized()); } @Test public void callHelooWithOAuth() throws Exception { ResultActions result = this.mvc.perform(post(OAUTH_END_POINT) .contentType(MediaType.MULTIPART_FORM_DATA) .params(getOAuthFormData()) .with(httpBasic(OAUTH_LZHENG_CLIENT, OAUTH_LZHENG_SECRET))) .andExpect(status().isOk()) .andExpect(content().string(containsString("access_token"))); String resultString = result.andReturn().getResponse().getContentAsString(); JacksonJsonParser jsonParser = new JacksonJsonParser(); String token = jsonParser.parseMap(resultString).get("access_token").toString(); this.mvc.perform(get(API_DEMO_HELLO) .header("Authorization", "Bearer " + token)) .andExpect(status().isOk()) .andExpect(content().string(HELLO_API_EXPECTED)); } private MultiValueMap<String, String> getOAuthFormData() { MultiValueMap<String, String> map = new LinkedMultiValueMap<>(); map.add("grant_type", "password"); map.add("username", "user"); map.add("password", "password"); return map; } }
Comments
Post a Comment