未在测试中评估的服务上的反应性 @PreAuthroize

Posted

技术标签:

【中文标题】未在测试中评估的服务上的反应性 @PreAuthroize【英文标题】:Reactive @PreAuthroize on service not evaluated in test 【发布时间】:2021-07-15 23:31:24 【问题描述】:

我想测试访问是否被服务拒绝,但 @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时不需要这样做?)并且还尝试直接在测试类上添加注释。

【问题讨论】:

【参考方案1】:

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

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

注意1:FooServiceImpl现在是通过@ContextConfiguration选择的,然后@AutowiredfooService通过参考它的界面来选择。

注意 2:以前我使用 @MockK 来表示 FooService 的依赖项(问题中未显示)。他们现在必须是@MockKBeans。

【讨论】:

以上是关于未在测试中评估的服务上的反应性 @PreAuthroize的主要内容,如果未能解决你的问题,请参考以下文章

尝试更改对象属性并保持反应性。属性或方法“vm”未在实例上定义,但在渲染期间被引用

未在 React 中呈现的元素上的触发事件侦听器

反应本机选择器未在android上显示

Vue转换未在按钮单击时触发

无法在反应测试库中使用模拟服务人员

Linux - 网络性能评估