在 Java Spring Boot

问题描述

在名为 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