首页 > 解决方案 > 未在测试中评估的服务上的反应性 @PreAuthroize

问题描述

我想测试访问被服务拒绝,但未@PreAuthorize评估。我可能缺少一些配置,但我不知道是什么。

这是服务

@Service
class FooServiceImpl : FooService {
  @PreAuthorize("denyAll")
  suspend fun bar() {
    println("I am not accessible")
  }
}

这是我期望的测试AccessDeniedException

@ExtendWith(SpringExtension::class, MockKExtension::class)
@Import(TestSecurityConfig::class)
internal class FooServiceImplTest {
  @InjectMockKs
  lateinit var fooService: FooServiceImpl
  @Test
  fun shouldDeny() {
    runBlocking {
      assertThrows<Exception> {
        fooService.bar()
      }
    }
  }
}

这是我导入的测试配置:

@TestConfiguration
@EnableReactiveMethodSecurity
@EnableWebFluxSecurity
class TestSecurityConfig {
  @Bean
  fun springSecurityFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain? {
    return http {
      csrf { disable() }
      formLogin { disable() }
      httpBasic { disable() }
      authorizeExchange {
        authorize(anyExchange, authenticated)
      }
    }
  }
}

测试失败:

Expected java.lang.Exception to be thrown, but nothing was thrown.

我也尝试添加@EnableGlobalMethodSecurity(prePostEnabled = true)(但据我了解,在使用时不需要这样做@EnableReactiveMethodSecurity?)并且还尝试直接在测试类上添加注释。

标签: spring-bootspring-securityspring-webflux

解决方案


我忘了考虑如何创建被测服务。在问题的设置中@InjectMockks,当然直接创建实例而不是在春季比赛中。没有上下文,就没有安全性交织在一起。

@ExtendWith(SpringExtension::class, MockKExtension::class)
@Import(TestSecurityConfig::class)
@ContextConfiguration(classes = [FooServiceImpl::class])
internal class FooServiceImplTest {
  @Autowired
  lateinit var fooService: FooService
  // ...
}

注 1:FooServiceImplnow 是通过 the 选择的@ContextConfiguration,然后@AutowiredtofooService是通过引用它的界面来选择的。

注意 2:以前我使用@MockK的是FooService. 他们现在必须是@MockKBeans。


推荐阅读