您好我设置了如下的基本Api测试:
@RunWith(SpringRunner.class)
@SpringBootTest
@WebAppConfiguration
@ActiveProfiles("test")
public abstract class BaseMockMvcSpec {
public static Logger log = LoggerFactory.getLogger(BaseMockMvcSpec.class);
@Autowired
private WebApplicationContext webApplicationContext;
private MockMvc mvc;
@Autowired
FilterChainProxy springSecurityFilterChain;
@Autowired
UserRepository users;
@Autowired
PasswordEncoder passwordEncoder;
@Autowired
CustomClientDetailsService clientDetialsService;
@Mock SecurityContext mockSecurityContext;
@Before
public void setUp() {
RestAssuredMockMvc.standaloneSetup(new AccountDetailsController());
mvc = MockMvcBuilders
.webAppContextSetup(webApplicationContext)
.apply(springSecurity(springSecurityFilterChain))
.build();
BaseClientDetails testClient = new ClientBuilder("testclient")
.secret("testclientsecret")
.authorizedGrantTypes("password")
.scopes("read", "wirte")
.autoApprove(true)
.build();
clientDetialsService.addClient(testClient);
User user = createDefaultUser("testuser", passwordEncoder.encode("testpassword"), "max", "Mustermann", new Email("test@lokata.de"));
users.deleteAll();
users.save(user);
log.info("setup BaseMockMvcSpec");
}
public String oauth(){
String token = "notValidToken";
try {
token = validAccessToken();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "Bearer " + token;
}
private String validAccessToken() throws Exception {
String username = "testuser";
String password = "testpassword";
MockHttpServletResponse response = mvc
.perform(post("/oauth/token")
.header("Authorization", "Basic "
+ new String(Base64Utils.encode(("testclient:testclientsecret")
.getBytes())))
.param("username", username)
.param("password", password)
.param("grant_type", "password"))
.andDo(print())
.andReturn().getResponse();
return new ObjectMapper()
.readValue(response.getContentAsByteArray(), OAuthToken.class)
.accessToken;
}
@JsonIgnoreProperties(ignoreUnknown = true)
private static class OAuthToken {
@JsonProperty("access_token")
public String accessToken;
}
}
我得到以下测试运行的输出:
2017-06-27 01:36:23.379 INFO 47446 --- [ Test worker] .b.t.c.SpringBootTestContextBootstrapper : Neither @ContextConfiguration nor @ContextHierarchy found for test class [de.example.microservice.authservice.verifier.tests.OauthserviceTest], using SpringBootContextLoader
2017-06-27 01:36:23.379 INFO 47446 --- [ Test worker] o.s.t.c.support.AbstractContextLoader : Could not detect default resource locations for test class [de.example.microservice.authservice.verifier.tests.OauthserviceTest]: no resource found for suffixes {-context.xml, Context.groovy}.
2017-06-27 01:36:23.379 INFO 47446 --- [ Test worker] t.c.s.AnnotationConfigContextLoaderUtils : Could not detect default configuration classes for test class [de.example.microservice.authservice.verifier.tests.OauthserviceTest]: OauthserviceTest does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
2017-06-27 01:36:23.383 INFO 47446 --- [ Test worker] .b.t.c.SpringBootTestContextBootstrapper : Found @SpringBootConfiguration de.example.microservice.authservice.AuthserverApplication for test class de.example.microservice.authservice.verifier.tests.OauthserviceTest
2017-06-27 01:36:23.385 INFO 47446 --- [ Test worker] .b.t.c.SpringBootTestContextBootstrapper : Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.security.test.context.support.WithSecurityContextTestExecutionListener, org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener, org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener]
2017-06-27 01:36:23.386 INFO 47446 --- [ Test worker] .b.t.c.SpringBootTestContextBootstrapper : Using TestExecutionListeners: [org.springframework.test.context.web.ServletTestExecutionListener@2efec58d, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@65dbe1b, org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener@4d31ce57, org.springframework.test.context.support.DirtiesContextTestExecutionListener@750239e7, org.springframework.test.context.transaction.TransactionalTestExecutionListener@2d885867, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener@464e86ab, org.springframework.security.test.context.support.WithSecurityContextTestExecutionListener@54eab43, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener@6167770c, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener@ec35027, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener@3c0ae48a, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener@4cee44fb, org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener@166b957d, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener@2bdadff]
2017-06-27 01:36:23.459 INFO 47446 --- [ Test worker] o.s.b.t.m.w.SpringBootMockServletContext : Initializing Spring FrameworkServlet ''
2017-06-27 01:36:23.459 INFO 47446 --- [ Test worker] o.s.t.web.servlet.TestDispatcherServlet : FrameworkServlet '': initialization started
2017-06-27 01:36:23.462 INFO 47446 --- [ Test worker] o.s.t.web.servlet.TestDispatcherServlet : FrameworkServlet '': initialization completed in 3 ms
2017-06-27 01:36:23.540 INFO 47446 --- [ Test worker] d.l.m.authservice.BaseMockMvcSpec : setup BaseMockMvcSpec
2017-06-27 01:36:23.564 DEBUG 47446 --- [ Test worker] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/oauth/token']
2017-06-27 01:36:23.564 DEBUG 47446 --- [ Test worker] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/oauth/token'; against '/oauth/token'
2017-06-27 01:36:23.564 DEBUG 47446 --- [ Test worker] o.s.s.web.util.matcher.OrRequestMatcher : matched
2017-06-27 01:36:23.564 DEBUG 47446 --- [ Test worker] o.s.security.web.FilterChainProxy : /oauth/token at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2017-06-27 01:36:23.564 DEBUG 47446 --- [ Test worker] o.s.security.web.FilterChainProxy : /oauth/token at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2017-06-27 01:36:23.565 DEBUG 47446 --- [ Test worker] o.s.security.web.FilterChainProxy : /oauth/token at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2017-06-27 01:36:23.565 DEBUG 47446 --- [ Test worker] o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@79e774c0
2017-06-27 01:36:23.565 DEBUG 47446 --- [ Test worker] o.s.security.web.FilterChainProxy : /oauth/token at position 4 of 12 in additional filter chain; firing Filter: 'LogoutFilter'
2017-06-27 01:36:23.565 DEBUG 47446 --- [ Test worker] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', GET]
2017-06-27 01:36:23.565 DEBUG 47446 --- [ Test worker] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'POST /oauth/token' doesn't match 'GET /logout
2017-06-27 01:36:23.565 DEBUG 47446 --- [ Test worker] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', POST]
2017-06-27 01:36:23.565 DEBUG 47446 --- [ Test worker] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/oauth/token'; against '/logout'
2017-06-27 01:36:23.565 DEBUG 47446 --- [ Test worker] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', PUT]
2017-06-27 01:36:23.565 DEBUG 47446 --- [ Test worker] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'POST /oauth/token' doesn't match 'PUT /logout
2017-06-27 01:36:23.565 DEBUG 47446 --- [ Test worker] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', DELETE]
2017-06-27 01:36:23.565 DEBUG 47446 --- [ Test worker] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'POST /oauth/token' doesn't match 'DELETE /logout
2017-06-27 01:36:23.565 DEBUG 47446 --- [ Test worker] o.s.s.web.util.matcher.OrRequestMatcher : No matches found
2017-06-27 01:36:23.565 DEBUG 47446 --- [ Test worker] o.s.security.web.FilterChainProxy : /oauth/token at position 5 of 12 in additional filter chain; firing Filter: 'ClientCredentialsTokenEndpointFilter'
2017-06-27 01:36:23.565 DEBUG 47446 --- [ Test worker] o.s.security.web.FilterChainProxy : /oauth/token at position 6 of 12 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
2017-06-27 01:36:23.565 DEBUG 47446 --- [ Test worker] o.s.s.w.a.www.BasicAuthenticationFilter : Basic Authentication Authorization header found for user 'testclient'
2017-06-27 01:36:23.565 DEBUG 47446 --- [ Test worker] o.s.s.authentication.ProviderManager : Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
2017-06-27 01:36:23.567 DEBUG 47446 --- [ Test worker] o.s.s.w.a.www.BasicAuthenticationFilter : Authentication success: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@7e2b6867: Principal: org.springframework.security.core.userdetails.User@81d402dd: Username: testclient; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Not granted any authorities; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Not granted any authorities
2017-06-27 01:36:23.567 DEBUG 47446 --- [ Test worker] o.s.security.web.FilterChainProxy : /oauth/token at position 7 of 12 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2017-06-27 01:36:23.567 DEBUG 47446 --- [ Test worker] o.s.security.web.FilterChainProxy : /oauth/token at position 8 of 12 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2017-06-27 01:36:23.567 DEBUG 47446 --- [ Test worker] o.s.security.web.FilterChainProxy : /oauth/token at position 9 of 12 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2017-06-27 01:36:23.567 DEBUG 47446 --- [ Test worker] o.s.s.w.a.AnonymousAuthenticationFilter : SecurityContextHolder not populated with anonymous token, as it already contained: 'org.springframework.security.authentication.UsernamePasswordAuthenticationToken@7e2b6867: Principal: org.springframework.security.core.userdetails.User@81d402dd: Username: testclient; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Not granted any authorities; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Not granted any authorities'
2017-06-27 01:36:23.567 DEBUG 47446 --- [ Test worker] o.s.security.web.FilterChainProxy : /oauth/token at position 10 of 12 in additional filter chain; firing Filter: 'SessionManagementFilter'
2017-06-27 01:36:23.567 DEBUG 47446 --- [ Test worker] s.CompositeSessionAuthenticationStrategy : Delegating to org.springframework.security.web.authentication.session.ChangeSessionIdAuthenticationStrategy@b7217c5
2017-06-27 01:36:23.567 DEBUG 47446 --- [ Test worker] o.s.security.web.FilterChainProxy : /oauth/token at position 11 of 12 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2017-06-27 01:36:23.567 DEBUG 47446 --- [ Test worker] o.s.security.web.FilterChainProxy : /oauth/token at position 12 of 12 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2017-06-27 01:36:23.567 DEBUG 47446 --- [ Test worker] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/oauth/token'; against '/oauth/token'
2017-06-27 01:36:23.567 DEBUG 47446 --- [ Test worker] o.s.s.w.a.i.FilterSecurityInterceptor : Secure object: FilterInvocation: URL: /oauth/token; Attributes: [fullyAuthenticated]
2017-06-27 01:36:23.567 DEBUG 47446 --- [ Test worker] o.s.s.w.a.i.FilterSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@7e2b6867: Principal: org.springframework.security.core.userdetails.User@81d402dd: Username: testclient; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Not granted any authorities; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Not granted any authorities
2017-06-27 01:36:23.568 DEBUG 47446 --- [ Test worker] o.s.s.access.vote.AffirmativeBased : Voter: org.springframework.security.web.access.expression.WebExpressionVoter@6b9626fc, returned: 1
2017-06-27 01:36:23.568 DEBUG 47446 --- [ Test worker] o.s.s.w.a.i.FilterSecurityInterceptor : Authorization successful
2017-06-27 01:36:23.568 DEBUG 47446 --- [ Test worker] o.s.s.w.a.i.FilterSecurityInterceptor : RunAsManager did not change Authentication object
2017-06-27 01:36:23.568 DEBUG 47446 --- [ Test worker] o.s.security.web.FilterChainProxy : /oauth/token reached end of additional filter chain; proceeding with original chain
2017-06-27 01:36:23.569 DEBUG 47446 --- [ Test worker] .s.o.p.e.FrameworkEndpointHandlerMapping : Looking up handler method for path /oauth/token
2017-06-27 01:36:23.569 DEBUG 47446 --- [ Test worker] .s.o.p.e.FrameworkEndpointHandlerMapping : Returning handler method [public org.springframework.http.ResponseEntity<org.springframework.security.oauth2.common.OAuth2AccessToken> org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken(java.security.Principal,java.util.Map<java.lang.String, java.lang.String>) throws org.springframework.web.HttpRequestMethodNotSupportedException]
2017-06-27 01:36:23.572 DEBUG 47446 --- [ Test worker] .o.p.p.ResourceOwnerPasswordTokenGranter : Getting access token for: testclient
2017-06-27 01:36:23.572 DEBUG 47446 --- [ Test worker] o.s.s.authentication.ProviderManager : Authentication attempt using de.example.microservice.authservice.authentication.behavior.CustomAuthenticationProvider
2017-06-27 01:36:23.656 DEBUG 47446 --- [ Test worker] o.s.s.w.a.ExceptionTranslationFilter : Chain processed normally
2017-06-27 01:36:23.656 DEBUG 47446 --- [ Test worker] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
MockHttpServletRequest:
HTTP Method = POST
Request URI = /oauth/token
Parameters = {username=[testuser], password=[testpassword], grant_type=[password]}
Headers = {Authorization=[Basic dGVzdGNsaWVudDp0ZXN0Y2xpZW50c2VjcmV0]}
Handler:
Type = org.springframework.security.oauth2.provider.endpoint.TokenEndpoint
Method = public org.springframework.http.ResponseEntity<org.springframework.security.oauth2.common.OAuth2AccessToken> org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken(java.security.Principal,java.util.Map<java.lang.String, java.lang.String>) throws org.springframework.web.HttpRequestMethodNotSupportedException
Async:
Async started = false
Async result = null
Resolved Exception:
Type = null
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 200
Error message = null
Headers = {X-Content-Type-Options=[nosniff], X-XSS-Protection=[1; mode=block], Cache-Control=[no-cache, no-store, max-age=0, must-revalidate], Pragma=[no-cache], Expires=[0], X-Frame-Options=[DENY], Content-Type=[application/json;charset=UTF-8]}
Content type = application/json;charset=UTF-8
Body = {"access_token":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50SWQiOiJmZjgwODA4MTVjZTZjMzBkMDE1Y2U2YzM2MmYzMDAyNyIsInVzZXJfbmFtZSI6InRlc3R1c2VyIiwic2NvcGUiOlsicmVhZCIsIndpcnRlIl0sIm9yZ2FuaXNhdGlvbiI6ImRlZmF1bHQiLCJleHAiOjE0OTg1NjMzODMsImF1dGhvcml0aWVzIjpbIlJPTEVfVVNFUiJdLCJqdGkiOiJlZGRmZWUyZS01NTU2LTQ1YWItOTIwMC02NThiM2FkNmRiNWYiLCJjbGllbnRfaWQiOiJ0ZXN0Y2xpZW50In0.bL9mLo1Ao6oUBA3BxrIIEWTEXVlTml5GqeoeAKqA_pXDFBn-gIRafRH8ji3BceTg-cjih_-cYYAbRiVmjsCAUd0nE-chwIwhwPp2WSAfgz9OHd531VsDOX7l8-vkR_BUKY5X02pIf2W9ZlsqCZ-isarRzWI_AQpNgqwoIDcICDeuB1lNWqkwtwmI_f0cF3u0J2FuQBvye3Sj4xXmrQU0awCj0F891v6bPqkM0Wc5G6i8Mm-n-OnRbMqcckfxAsSqtDEYrDe3T6otFfREZ6AYTefMzQWYbYXDK0tCkohH46hNmKlbrXNWUrnwYLDeCZyOGm8bCrOihDzjYJgw5RshKQ","token_type":"bearer","expires_in":43199,"scope":"read wirte","accountId":"ff8080815ce6c30d015ce6c362f30027","organisation":"default","jti":"eddfee2e-5556-45ab-9200-658b3ad6db5f"}
Forwarded URL = null
Redirected URL = null
Cookies = []
2017-06-27 01:36:23.684 INFO 47446 --- [ Test worker] ilder$StaticRequestMappingHandlerMapping : Mapped "{[/api/me],methods=[GET],produces=[application/json;charset=UTF-8]}" onto public java.security.Principal de.example.microservice.authservice.rest.behavior.AccountDetailsController.user(java.security.Principal)
2017-06-27 01:36:23.692 INFO 47446 --- [ Test worker] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.test.web.servlet.setup.StubWebApplicationContext@734a6c74
2017-06-27 01:36:23.696 INFO 47446 --- [ Test worker] o.s.mock.web.MockServletContext : Initializing Spring FrameworkServlet ''
2017-06-27 01:36:23.696 INFO 47446 --- [ Test worker] o.s.t.web.servlet.TestDispatcherServlet : FrameworkServlet '': initialization started
2017-06-27 01:36:23.696 INFO 47446 --- [ Test worker] o.s.t.web.servlet.TestDispatcherServlet : FrameworkServlet '': initialization completed in 0 ms
TestException是
java.lang.IllegalArgumentException: json string can not be null or empty
at com.jayway.jsonpath.internal.Utils.notEmpty(Utils.java:386)
at com.jayway.jsonpath.internal.JsonContext.parse(JsonContext.java:81)
at com.jayway.jsonpath.JsonPath.parse(JsonPath.java:596)
at de.example.microservice.authservice.verifier.tests.OauthserviceTest.validate_shouldReturnAccountDetails(OauthserviceTest.java:29)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method
我想自动生成的测试没有执行,但不知道如何调试它们。 get Oauth2令牌完美无缺,并且在验证器类中执行oath()方法。
答案 0 :(得分:1)
是。只需在EXPLICIT模式下运行插件。这样你可以配置restassured来拍摄任何URL,你可以设置你想要的基类。示例https://cloud.spring.io/spring-cloud-contract/spring-cloud-contract.html#_working_with_context_paths
答案 1 :(得分:1)
我最终得到了以下测试设置:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
@ContextConfiguration
@WebAppConfiguration
@ActiveProfiles("test")
public abstract class UserDetailsControllerTestBase {
public static Logger log = LoggerFactory.getLogger(UserDetailsControllerTestBase.class);
@Autowired
private WebApplicationContext webApplicationContext;
private MockMvc mvc;
@Autowired
FilterChainProxy springSecurityFilterChain;
@Mock SecurityContext mockSecurityContext;
@Before
public void setUp() {
RestAssured.enableLoggingOfRequestAndResponseIfValidationFails();
//RestAssured.baseURI="http://localhost";
//RestAssured.port = port;
mvc = MockMvcBuilders
.webAppContextSetup(webApplicationContext)
.defaultRequest(get("/api/me").with(user("user").roles("USER")))
.apply(springSecurity(springSecurityFilterChain))
.build();
RestAssuredMockMvc.mockMvc(mvc);
}
public String oauth(){
String token = "notValidToken";
try {
token = validAccessToken();
} catch (Exception e) {
e.printStackTrace();
}
return "Bearer " + token;
}
public void assertIsNull(Object value){
assertThat(value, is(nullValue()));
}
private String validAccessToken() throws Exception {
String username = "user";
String password = "password";
MockHttpServletResponse response = mvc
.perform(post("/oauth/token")
.header("Authorization", "Basic "
+ new String(Base64Utils.encode(("client:clientsecret")
.getBytes())))
.param("username", username)
.param("password", password)
.param("grant_type", "password"))
.andDo(print())
.andReturn().getResponse();
return new ObjectMapper()
.readValue(response.getContentAsByteArray(), OAuthToken.class)
.accessToken;
}
@JsonIgnoreProperties(ignoreUnknown = true)
private static class OAuthToken {
@JsonProperty("access_token")
public String accessToken;
}
}
查看示例Solution存储库以获取更多详细信息