问题描述
在名为 ProductController 的 RestController 中,我定义了一些 PreAuthorize 函数,例如:
@PreAuthorize("@userIsOwnerOfEntity.apply(#id,principal.claims['user_id'])")
此函数会在用户保存/更新实体之前检查 userId 是否为产品的实际所有者。这是另一个名为 ProductControllerSecurity.class 的文件中的实现,该文件被注释为服务。
@Autowired
public GetProductImpl getProductImpl;
@Bean
public BiFunction<ProductDto,String,Boolean> userIsOwnerOfEntity() {
return (product,userId) -> {
Product check = getProductImpl.execute(product.getProductId());
return check.getUserId().toString().equals(userId);
};
}
现在我想在我的 ProductControllerTest.class 中模拟 userIsOwnerOfEntity 功能,但我碰壁了。
在我的测试中,我有以下模拟实现:
@Autowired public BiFunction<ProductDto,Boolean> userIsOwnerOfEntity;
when(userIsOwnerOfEntity.apply(any(ProductDto.class),any(String.class))).thenReturn(true);
该测试导入一个名为 ProductControllerSecurityTest.class 的文件,该文件具有以下 Bean:
@MockBean(name="userIsOwnerOfEntity") public BiFunction<ProductDto,Boolean> userIsOwnerOfEntity;
所以我假设模拟的 SpEL 函数应该只返回 true。但我收到以下错误;
org.springframework.web.util.nestedservletexception:请求处理失败;嵌套异常是 java.lang.NullPointerException:无法调用“java.lang.Boolean.booleanValue()”,因为“org.springframework.expression.Expression.getValue(org.springframework.expression.EvaluationContext,java.lang.类)”为空
我相信这告诉我 SpEL 函数没有返回 true。
有什么指点吗?
解决方法
因此,我需要将@SpringBootTest 与@AutoConfigureMockMvc 一起使用,而不是使用@WebMvcTest。然后它正确地模拟了 SpEL 表达式。
when(userIsOwnerOfEntity.apply(any(ProductDto.class),anyString())).thenReturn(true);
上面的代码现在按预期运行。
这解决了以下错误:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalArgumentException
Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1058E: A problem occurred when trying to resolve bean 'Could not resolve bean reference against BeanFactory'
Caused by: org.springframework.expression.AccessException: Could not resolve bean reference against BeanFactory
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'userIsOwnerOfEntity' available