对Spring引导测试特定的@TestConfiguration感到困惑

时间:2018-01-28 06:01:23

标签: spring spring-boot spring-test spring-test-mvc spring-boot-test

根据Spring Boot Docs,应自动检测嵌套@TestConfiguration

但是在我的测试代码中,当我运行整个测试类时,它是有问题的,即使我通过@Import显式添加它也没有检测到。测试代码结构如下:

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@RunWith(SpringRunner.class)
//@Import(IntegrationTests.TestSecurityConfig.class)
public class IntegrationTests {

// test methods

   // test configuration
   @TestConfiguration
   static class TestSecurityConfig {}

}

当我单独运行单个测试用例(测试方法)时,所有测试都按预期传递,但是当我直接运行测试类时,某些测试失败,@TestConfiguration为不适用于测试。

IntegrationTests的完整代码为here

更新: 我的代码中添加了一种解决方法,以便通过测试。

@TestComponent
@Slf4j
static class TestUserDetailsService implements UserDetailsService {

    private final PasswordEncoder passwordEncoder;

    TestUserDetailsService(PasswordEncoder passwordEncoder) {
        this.passwordEncoder = passwordEncoder;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UserDetails user = User.withUsername("user")
            .password(passwordEncoder.encode("password"))
            .roles("USER")
            .accountExpired(false)
            .accountLocked(false)
            .credentialsExpired(false)
            .disabled(false)
            .build();

        UserDetails admin = User.withUsername("admin")
            .password(passwordEncoder.encode("password"))
            .roles("ADMIN")
            .accountExpired(false)
            .accountLocked(false)
            .credentialsExpired(false)
            .disabled(false)
            .build();

        log.debug("dummy user:" + user);
        log.debug("dummy admin:" + admin);


        if ("user".equals(username)) {
            return user;
        } else {
            return admin;
        }
    }
}

@TestConfiguration
@Slf4j
@Import(TestUserDetailsService.class)
@Order(-1)
static class TestSecurityConfig extends WebSecurityConfigurerAdapter {

    @Inject
    PasswordEncoder passwordEncoder;

    @Inject
    UserDetailsService userDetailsService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .httpBasic()
            .and()
            .authorizeRequests()
            .antMatchers(HttpMethod.GET, "/posts/**").permitAll()
            .antMatchers(HttpMethod.DELETE, "/posts/**").hasRole("ADMIN")
            .anyRequest().authenticated()
            .and()
            .csrf().disable();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

}

}

仍有一些事情使我感到困惑。

  1. 在测试类中,为什么@TestConfiguration无法检测位于同一测试中的@TestComponent,我必须添加@Import来修复它。
  2. security section of Spring Boot Docs中所述,我在考虑定义一个UserDetailsService bean就足够了,它将为用户提供安全保障,但它在测试中无效。我必须配置一个WebSecurityConfigurerAdapter并公开AuthenticationManager进行测试,为什么?如上所述,如果没有为测试定义WebSecurityConfigurerAdapter,则逐个运行测试就会更加困惑。
  3. @TestConfiguration注释WebSecurityConfigurerAdapter没有获得更高的订单,我必须在其上添加@Order。我在想一个@TestConfiguration bean应该自动获取Primary并在我的应用程序配置中替换bean,对吗?

0 个答案:

没有答案