目前我有几个单元测试工作正常。 在我的单元测试中,在init上,我包含了以下代码:
@Mock
private UsersServices usersServices;
@InjectMocks
private UsersController usersControllers;
@Before
public void init() {
this.mvc = MockMvcBuilders.standaloneSetup(usuariosController)
.addFilter(springSecurityFilterChain)
.setControllerAdvice(new UsuariosControllerAdvice(logService)).build();
}
这很有效,但忽略了一些授权注释,如@PreAuthorize
。 (在我的WebSecurityConfig中,我已经添加了@EnableGlobalMethodSecurity(prePostEnabled = true)
注释。
所以,过了一段时间,我发现了以下代码:
@Mock
private UsersServices usersServices;
@InjectMocks
private UsersController usersControllers;
@Autowired
private WebApplicationContext wac;
@Before
public void init() {
this.mvc = MockMvcBuilders
.webAppContextSetup(wac)
.addFilter(springSecurityFilterChain)
apply(SecurityMockMvcConfigurers.springSecurity(springSecurityFilterChain))
.build();
}
现在,授权注释(@PreAuthorize
)有效,但UsersServices
模拟没有。当我在单元测试中调用我的控制器方法时,调用了真实的UserServices
,而不是模拟。
这是一个模拟UserServices
:
when(usersServices.getUserAvatar(anyString())).thenReturn(
CompletableFuture.completedFuture(Optional.empty()));
MvcResult result = mvc.perform(
get("/api/users/avatar/{login:.+}", "mock.user")
.header("Authorization", testHelpers.buildJwtToken("USER")))
.andReturn();
mvc.perform(asyncDispatch(result))
.andExpect(status().isNotFound());
没有standaloneSetup
,就会调用真实的userServices.getUserAvatar
。
答案 0 :(得分:1)
之所以发生这种情况,是因为您的WebApplicationContext
无法通过模拟UsersController
了解您的UsersServices
。要解决此问题,您有两种选择:
第一种选择是使用
@MockBean
private UsersServices usersServices;
而不是:
@Mock
private UsersServices usersServices;
这会将模拟bean添加到应用程序上下文中,以便Spring知道它,因此将使用它而不是真实的。
第二个选项是手动将控制器直接设置在WebApplicationContext
内。此选项不应该“在家中尝试”,但对于因为旧的春季版本而没有@MockedBean
的情况,可以采用解决方法:
AutowireCapableBeanFactory factory = wac.getAutowireCapableBeanFactory();
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) factory;
registry.removeBeanDefinition(beanId);
//create newBeanObj through GenericBeanDefinition
registry.registerBeanDefinition(beanId, newBeanObj);