gpt4 book ai didi

Spring AOP Aspect 无法使用 Mockito 工作

转载 作者:行者123 更新时间:2023-12-02 01:14:20 26 4
gpt4 key购买 nike

我有一个@Aspect,它编织了我所有 Controller 操作方法的执行。当我运行系统时它工作正常,但在单元测试中却不行。我按以下方式使用 Mockito 和 junit:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:**/spring-context.xml")
@WebAppConfiguration
public class UserControllerTest {
private MockMvc mockMvc;

@Mock
private RoleService roleService;

@InjectMocks
private UserController userController;

@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
...
mockMvc = MockMvcBuilders.standaloneSetup(userController).build();
}
...
}

使用mockMvc.perform()进行一些@Test

我的方面是:

@Pointcut("within(@org.springframework.stereotype.Controller *)")
public void controller() { }

@Pointcut("execution(* mypackage.controller.*Controller.*(..))")
public void methodPointcut() { }

@Around("controller() && methodPointcut()")
...

最佳答案

首先需要按照 Jason 的建议使用 webAppContextSetup:

@Autowired
private WebApplicationContext webApplicationContext;

@Before
public void setUp() throws Exception {
...
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}

此时应该触发切面,但 Mockito 不会注入(inject)模拟。这是因为 Spring AOP 使用代理对象,并且模拟被注入(inject)到该代理对象而不是被代理对象。要解决此问题,需要解开对象并使用 ReflectionUtils 而不是 @InjectMocks 注释:

private MockMvc mockMvc;

@Mock
private RoleService roleService;

private UserController userController;

@Autowired
private WebApplicationContext webApplicationContext;

@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
UserController unwrappedController = (UserController) unwrapProxy(userController);
ReflectionTestUtils.setField(unwrappedController, "roleService", roleService);
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}

...

public static final Object unwrapProxy(Object bean) throws Exception {
/*
* If the given object is a proxy, set the return value as the object
* being proxied, otherwise return the given object.
*/
if (AopUtils.isAopProxy(bean) && bean instanceof Advised) {
Advised advised = (Advised) bean;
bean = advised.getTargetSource().getTarget();
}
return bean;
}

此时,任何对when(...).thenReturn(...)的调用都应该正常工作。

这里有解释:http://kim.saabye-pedersen.org/2012/12/mockito-and-spring-proxies.html

关于Spring AOP Aspect 无法使用 Mockito 工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16902389/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com