Mockito不会嘲笑@PreAuthorize和Spring Boot。



我对Spring Security(使用Spring Boot 1.3.1.REASE)和Mockito有一个很大的问题。

当我在SampleService类的方法doIt()上使用@PreAuthorize时,Mockito在测试doItTest()期间不会在SampleService内部嘲笑方法getValue()(在SampleDao类上声明)。

结果是:java.lang.AssertionError: expected:<false> but was:<true>

它的发生是因为指令

Mockito.when(dao.getValue()).thenReturn(ctrl);

当我在SampleService类的方法doIt()中使用@PreAuthorize时,它不起作用。

当我从方法doIt()中删除@PreAuthorize时,测试doItTest()运行良好(Mockito正在嘲笑getValue())。

但是,当我在方法doIt()上使用@PreAuthorize运行另一个测试doItDeniedTest()时,它运行良好,因为@PreAuthorize抛出AccessDeniedException。

我该怎么修?

谢谢大家。

代码:

@SpringBootApplication
public class AppApplication {
    public static void main(String[] args) {
        SpringApplication.run(AppApplication.class, args);
    }
}
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
   @Autowired
   private LogoutHandler logoutHandler;
   @Autowired
   private AuthenticationSuccessHandler authenticationSuccessHandler;
   @Autowired
   private AccessDeniedHandler accessDeniedHandler;
   @Autowired
   private AuthenticationFailureHandler authenticationFailureHandler;
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
        .authorizeRequests()
            .antMatchers("/public/**").permitAll()
            .antMatchers("/error/**").permitAll()
            .and()
        .authorizeRequests()
            .antMatchers("/").permitAll()
            .antMatchers("/adm/**").hasAnyRole(Role.ROOT,Role.ADM)
            .anyRequest().authenticated()
            .and()
        .formLogin()
            .loginPage("/login")
            .successHandler(authenticationSuccessHandler)
            .failureHandler(authenticationFailureHandler)
            .defaultSuccessUrl("/home",true)
            .permitAll()
            .and()
        .logout()
            .logoutSuccessUrl("/login")
            .permitAll()
            .addLogoutHandler(logoutHandler)
            .and()
         .exceptionHandling()
            .accessDeniedHandler(accessDeniedHandler);
    }
}

@Repository
public class SampleDao implements Dao {
   @Override
   public boolean getValue(){
     return true;
   }
}
@Service
public class SampleService implements Service{
   @Autowired
   private Dao dao;
   @Override
   @PreAuthorize(value="hasRole('USR')")
   public boolean doIt(){
     return dao.getValue();
   }
}

我的测试课程是:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {AppApplication.class})
@WebAppConfiguration
public class SampleServiceImplTest {
    @Mock
    private SampleDaoImpl dao;
    @Autowired
    @Qualifier("sampleServiceImpl")
    @InjectMocks
    private SampleService svc;
    @Before
    public void initMocks(){
        MockitoAnnotations.initMocks(this); 
    }   

    @Test(expected=AccessDeniedException.class)
    @WithMockUser(username="usr",roles={"ROOT"})
    public void doItDeniedTest() {
        svc.doIt();
    }
    @Test
    @WithMockUser(username="usr",roles={"USR"})
    public void doItTest() {
    Boolean ctrl = Boolean.FALSE;
    Mockito.when(dao.getValue()).thenReturn(ctrl);
    Boolean rt = svc.doIt();
    assertEquals(ctrl,rt);      
    }
}

您正在将集成测试与单元测试相结合。不要那样做。你有两个选择:

  1. 根本不创建Spring上下文,在测试中显式地连接类,并使用类似的mocking。这将是单元测试
  2. 如果您想在集成测试中模拟springbean,您需要将其注册到spring上下文中。我写了这篇关于这个主题的博客文章

阅读博客后,我更改了我的测试类。

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {AppApplication.class,TestConfiguration.class})
@WebAppConfiguration
public class SampleServiceImplTest {
    @Configuration
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    protected static class TestConfiguration {
         @Bean
         @Primary
         public SampleDaoImpl gatSampleDaoImpl(){
               return Mockito.mock(SampleDaoImpl.class);
         }
    }
    @Autowired
    private SampleDaoImpl dao;
    @Autowired
    private SampleService svc;
    @Before
    public void initMocks(){
        MockitoAnnotations.initMocks(this); 
    }   

    @Test(expected=AccessDeniedException.class)
    @WithMockUser(username="usr",roles={"ROOT"})
    public void doItDeniedTest() {
        svc.doIt();
    }
    @Test
    @WithMockUser(username="usr",roles={"USR"})
    public void doItTest() {
    Boolean ctrl = Boolean.FALSE;
    Mockito.when(dao.getValue()).thenReturn(ctrl);
    Boolean rt = svc.doIt();
    assertEquals(ctrl,rt);      
    }
}

相关内容

  • 没有找到相关文章

最新更新