在我的项目中,我使用Spring安全性使用jwt令牌进行日志记录。一切工作,但我遇到了一个问题,当尝试使用单元测试。我在我的SecurityConfig中定义了所有的认证和授权类,并有一个AuthAPI来登录或注销。这些类有许多bean,例如AuthenticationManager,UserService…
当我使用单元测试时,出现错误并告诉我添加参数,如AuthenticationManager,UserService如下:
Parameter 0 of constructor in com.myproject.auth.authAPI.AuthApi required a bean of type 'com.myproject.auth.service.UserService' that could not be found.
这是我的安全配置和AuthApi:
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private static final String[] AUTH_WHITELIST = {
"/auth/login/**",
"/auth/refresh/token/**",
"/auth/register/**",
};
private final UserDetailsService userDetailsService;
private final BCryptPasswordEncoder bCryptPasswordEncoder;
private final TokenBlacklistService tokenBlacklistService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.authorizeRequests().antMatchers(AUTH_WHITELIST).permitAll();
http.authorizeRequests().antMatchers(HttpMethod.GET, "/auth/user/**").hasAuthority("ROLE_USER");
http.authorizeRequests().antMatchers(HttpMethod.POST, "/api/user/save/**").hasAuthority("ROLE_ADMIN");
http.authorizeRequests().anyRequest().authenticated();
http.exceptionHandling().authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));
//http.addFilter(customAuthenticationFilter);
http.addFilterBefore(new CustomAuthorizationFilter(tokenBlacklistService), UsernamePasswordAuthenticationFilter.class);
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@RestController
@RequestMapping("/auth")
@RequiredArgsConstructor
public class AuthApi {
private final UserService userService;
private final TokenBlacklistService tokenBlacklistService;
private final AuthenticationFilter authenticationFilter;
@GetMapping("/users")
public ResponseEntity<List<User>> getUser(){
return ResponseEntity.ok().body(userService.getUsers());
}
//other methods
}
这是我的单元测试(在这种情况下,我也不知道我写的单元测试是否正确,这是我第一次写单元测试):
@RunWith(SpringRunner.class)
@WebMvcTest(AuthApi.class)
class AppApiTests {
@Autowired
private MockMvc mockMvc;
@Test
void testGetUsers() throws Exception {
this.mockMvc.perform(get("/auth/users")
.accept(MediaType.APPLICATION_JSON)
.header(HttpHeaders.AUTHORIZATION, "Bearer token")
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk());
}
}
我不知道如何在单元测试中添加依赖来解决这个问题,或者可能我写错了测试用例,请帮助我。非常感谢!
有问题的AuthApi类使用了3个其他类(UserService, TokenBlacklistService和AuthenticationFilter),并且在您的测试中,它们没有在使用@WebMcvTest生成的上下文中定义。
要解决这个问题,可以:
- 可以使用@SpringBootTest而不是@WebMvcTest,但记住这将启动完整的springboot应用程序上下文,然后您需要在测试上下文 中提供所需的依赖项
- 或者,在测试中对所有3个服务使用@MockBean。这将在测试执行期间模拟bean,而不会调用实际的服务。这可以用来测试请求映射等是否按预期工作…像这样:
@MockBean UserService userservice;
@MockBean TokenBlacklistService tokenBlacklistService;
如果您还想测试安全配置,那么您需要在测试中单独包含这些配置,并在那里定义所需的依赖项。