当前位置: 首页 > 知识库问答 >
问题:

如何使用Spring Security测试控制器

司寇光华
2023-03-14

我有下一个Rest控制器

@RestController
@AllArgsConstructor
@Slf4j
@RequestMapping("api/v1/user")
public class UserControllerImpl implements UserController {

    public final UserService userService;
    public final JwtProvider jwtProvider;
    public final JwtFilter jwtFilter;

    @PostMapping(value = "/registration")
    public void registration(@RequestBody UserDto user) {
        log.info("Registration user: Got a registration request for user {}", user.getEmail());
        userService.save(user);
        log.info("Registration user: successful, new user saved in DB");
    }

    @PreAuthorize("hasAnyRole('ADMIN', 'USER', 'SUPER')")
    @PutMapping(value = "/update")
    public void update(
            ServletRequest servletRequest,
            @RequestBody UserDto userDto
    ) {
        log.info("Update user: Got a update request for user {}", userDto);
        userService.update(servletRequest, userDto);
        log.info("Update user: successful update");
    }
}

我将Spring Security用于以下配置:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@AllArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    public final JwtFilter jwtFilter;
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .httpBasic().disable()
                .csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers("/api/v1/user/**").permitAll()
                .anyRequest().authenticated()
                .and()
                .addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

我想为我的控制器编写单元测试。我写了下一个测试,但是它们工作得不好:

@Import(JwtProvider.class)
@WebMvcTest(value = UserControllerImpl.class)
class UserControllerTest {

    @MockBean
    private UserServiceImpl userServiceImpl;

    @Autowired
    private MockMvc mockMvc;
@Test
    void registrationRequestExpectOkAndVerifySaveOnce() throws Exception {
        doNothing().when(userServiceImpl).save(any());
        mockMvc.perform(post("/api/v1/user/registration")
                        .contentType(MediaType.APPLICATION_JSON)
                        .content("{\"firstName\": \"mockFirstName\",\"password\": \"mockPassword\"}"))
                .andExpect(status().isOk());
        verify(userServiceImpl, times(1)).save(any());
    }

    @Test
    void update() throws Exception {
        doNothing().when(userServiceImpl).update(any(), any());
        mockMvc.perform(put("/api/v1/user/update")
                        .contentType(MediaType.APPLICATION_JSON)
                        .content("{\"firstName\": \"mockFirstName\",\"password\": \"mockPassword\"}"))
                .andExpect(status().isOk());
        verify(userServiceImpl, times(1)).update(any(), any());
    }
}

当我开始测试时,我得到了状态404。如果在安全配置中删除@EnableGlobalmetodSecurity(prePostEnable=true),测试正在工作,但不工作@PreAuthorize。我有一些问题:

  • 如果prespenabled=true,为什么我得到404
  • 我怎样才能解决这个问题
  • 如果我要为具有允许角色和不允许角色的用户编写方法更新测试,我该怎么做

共有1个答案

诸葛绍元
2023-03-14

您只需要添加以下Spring Security Test依赖项;

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-test</artifactId>
</dependency>

并使用@RevMockUser注释来测试控制器方法。

@Test
@WithMockUser(roles = {"ADMIN"})
void update() throws Exception {
    doNothing().when(userServiceImpl).update(any(), any());
    mockMvc.perform(put("/api/v1/user/update")
                    .contentType(MediaType.APPLICATION_JSON)
                    .content("{\"firstName\": \"mockFirstName\",\"password\": \"mockPassword\"}"))
            .andExpect(status().isOk());
    verify(userServiceImpl, times(1)).update(any(), any());
}

但是您的SecurityConfig有一个问题。以下行禁用了Spring Security的更新和注册网址。您需要先纠正这个问题。

antMatchers("/api/v1/user/**").permitAll()
 类似资料:
  • 因此,我正在进行我的第一个Spring Boot项目,我一直在进行测试。我查了很多例子,但似乎都不管用。 这是我的控制器的当前测试: 这是可行的,但在sonarqube上,我发现我的代码覆盖率为0%,而我似乎找不到一个测试,它的覆盖率甚至超过了零。有谁能给我一个关于如何为控制器编写一个好的单元测试的例子,然后我就可以根据您的例子自己解决这个问题。 这是我的控制器: 这是我的服务(以防您需要): 还

  • 问题内容: 初始化JavaFX运行时的正确方法是什么,以便您可以对使用并发工具和的控制器进行单元测试(使用JUnit)? 从该方法调用会导致死锁。如果未调用,则会引发以下错误: 后续:这是我根据@SergeyGrinev的建议一直使用的主题。 问题答案: 调用由是正确的做法。请注意,这不会将控制权返回给调用代码。因此,您必须将其包装到中。 7年后的更新: 使用TestFX!它将以适当的方式进行启动

  • 问题内容: 我正在使用spring 3.2.0和junit 4 这是我需要测试的控制器方法 spring-servlet config is: This is my test class : 如何使用MockMvc测试此方法? 问题答案: 你可以使用以下注释来使用应用程序调度程序servlet xml。以下示例使用路径/ mysessiontest设置了一些会话属性并期望返回某个视图来命中控制器:

  • 本文向大家介绍SpringSecurity 测试实战,包括了SpringSecurity 测试实战的使用技巧和注意事项,需要的朋友参考一下 引言 试题管理系统的安全模块使用Spring Security,代码从原华软仓库移植,在移植的过程中,发现原测试编写的不好,遂在新系统中对安全模块测试进行了重构。 Spring 测试 添加@SpringBootTest注解,意为这是一个基于SpringBoot

  • 英文原文:http://emberjs.com/guides/testing/testing-controllers/ 单元测试方案和计算属性与之前单元测试基础中说明的相同,因为Ember.Controller集成自Ember.Object。 针对控制器的单元测试使用ember-qunit框架的moduleFor来做使这一切变得非常简单。 测试控制器操作 下面给出一个PostsController