【发布时间】:2020-09-05 15:50:42
【问题描述】:
我有一个 Spring Boot Rest 应用程序,我在其中使用 JWT 进行身份验证,当我启动应用程序时它工作正常。
我只是想添加一些测试用例,但我无法解决这个问题(我用mvn test 运行测试用例:
错误表明 Spring 无法创建 userDetailsService bean,但这似乎不正确,因为我的应用程序可以毫无问题地运行。
不是:我尝试通过 @MockBean 添加 userdetailservice 模拟。但是这次 spring 为 MyAuthenticationEntryPoint 显示了相同的错误。我认为应该有一个解决方案来自动添加所有配置,或者避免所有这些配置。
[ERROR] verifyRegisterUserHttpRequest Time elapsed: 0.008 s <<< ERROR!
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'securityConfiguration': Unsatisfied dependency expressed
through field 'userDetailsService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type 'com.myProjects.sample.security.MyUserDetailsService' available: expected at least 1 bean which qualifies as autowire candidate.
Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
- 这里是测试类:
package com.myProjects.sample.controller;
@WebMvcTest(controllers = RegisterController.class)
public class RegisterControllerTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;
@MockBean
private RegisterService registerService;
@MockBean
private ValidationService validationService;
// 1. Verifying Http Request Matching
@Test
public void verifyRegisterUserHttpRequest() throws Exception {
NewCustomerRequest requestBody = new NewCustomerRequest();
requestBody.setEmailAddress("sample@sample.com");
requestBody.setPhoneNumber("01112223344");
requestBody.setPassword("password");
requestBody.setPasswordVerify("password");
mockMvc.perform(post(MyWebUrls.API.API + MyWebUrls.Register.REGISTER_USER)
.content(objectMapper.writeValueAsString(requestBody))
.contentType("application/json"))
.andExpect(status().isOk());
}
}
- RegisterController 和 SecurityConfiguration
package com.myProjects.sample.controller;
@RestController
@RequestMapping(MyWebUrls.API.API)
public class RegisterController {
@Autowired
private RegisterService registerService;
@Autowired
private ValidationService validationService;
@PostMapping(MyWebUrls.Register.REGISTER_USER)
public ResponseEntity<?> registerUser(@Valid @RequestBody NewCustomerRequest newCustomerRequest, BindingResult bindingResult){
String validationResultMessage = validationService.getFirstValidationErrorMessage(bindingResult);
// ...
}
}
}
package com.myProjects.sample.security;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(
// securedEnabled = true,
// jsr250Enabled = true,
prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private MyUserDetailsService userDetailsService;
@Autowired
private MyAuthenticationEntryPoint unauthorizedHandler;
@Autowired
private CustomAccessDeniedHandler accessDeniedHandler;
@Bean
public AuthTokenFilter authJwtTokenFilter(){
return new AuthTokenFilter();
}
@Override
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
// ....
- 还可以查看我的自定义详细信息服务类
package com.myProjects.sample.security;
@Service
public class MyUserDetailsService implements UserDetailsService {
@Override
@Transactional
public UserDetails loadUserByUsername(String emailOrMobilePhone) throws UsernameNotFoundException {
// ...
}
}
【问题讨论】:
-
您还需要在测试类中自动装配或模拟您的 userDetialService
-
我已经尝试过了,但是这次同样的错误发生在名为 AuthenticationEntryPoint 的 bean 上,然后是 Jwt ......我认为在这种情况下应该有一种方法不启用安全性
-
一种方法是创建配置文件并使用@Profile("!test") 装饰你的spring bean,并在运行测试类时将装饰器保持为@ActiveProfiles("test")
标签: java spring spring-boot spring-test spring-test-mvc