问题描述
我有一个Spring Boot应用程序,想为控制器编写集成测试。这是我的SecurityConfig
:
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final MyUserDetailsService userDetailsService;
private final SessionAuthenticationProvider authenticationProvider;
private final SessionAuthenticationFilter sessionAuthenticationFilter;
@Override
public void configure(WebSecurity web) {
//...
}
@Override
protected void configure(HttpSecurity http) throws Exception {
/...
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider);
auth.userDetailsService(userDetailsService);
}
}
这是我的控制者:
@RestController
public class MyController {
//...
@GetMapping("/test")
public List<TestDto> getAll(){
List<TestDto> tests= testService.findAll(authService.getLoggedUser().getId());
return mapper.toTestDtos(tests);
}
}
我创建了一个测试(JUnit 5):
@WebMvcTest(TestController.class)
class TestControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean(name = "mockTestService")
private TestService testService;
@Autowired
private TestMapper mapper;
@MockBean(name = "mockAuthService")
private AuthService authService;
private Test test;
@BeforeEach
void setUp() {
User user = new Test();
user.setId("userId");
when(authService.getLoggedUser()).thenReturn(user);
test = new Facility();
test.setId("id");
test.setName("name");
when(testService.findAll("userId")).thenReturn(singletonList(test));
}
@Test
void shouldReturnAllIpaFacilitiesForCurrentTenant() throws Exception {
mockMvc.perform(get("/test").contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$..id").value(test.getId()))
.andExpect(jsonPath("$..timeOut").value(test.getName()));
}
}
开始测试时,出现异常:Consider defining a bean of type 'com.auth.MyUserDetailsService' in your configuration.
发生这种情况是因为我没有在测试中使用UserDetailsService bean。我该怎么办:
-
SecurityConfig需要添加3个bean,例如:
@MockBean MyUserDetailsService userDetailsService; @MockBean SessionAuthenticationProvider authenticationProvider; @MockBean SessionAuthenticationFilter sessionAuthenticationFilter;
-
添加SecurityConfig的测试实现
-
其他东西
哪种方法更好?
解决方法
要使用@WebMvcTest
为您的控制器端点编写测试,我将使用MockMvc
和Spring Security的强大集成。
确保您具有以下依赖性:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
下一步,您可以为MockMvc
请求模拟经过身份验证的用户,还可以设置用户名,角色等。
使用注释在SecurityContext
内填充经过身份验证的用户进行测试:
@Test
@WithMockUser("youruser")
public void shouldReturnAllIpaFacilitiesForCurrentTenant() throws Exception {
// ...
}
或使用SecurityMockMvcRequestPostProcessors
之一:
this.mockMvc
.perform(
post("/api/tasks")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"taskTitle\": \"Learn MockMvc\"}")
.with(csrf())
.with(SecurityMockMvcRequestPostProcessors.user("duke"))
)
.andExpect(status().isCreated());
您可以在此here上找到更多信息。