Spring AOP Aspect不使用Mockito

时间:2013-06-03 17:26:14

标签: spring junit aop mockito

我有@Aspect编织所有控制器操作方法的执行。它在我运行系统时工作正常,但在单元测试中没有。我用以下方式使用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();
    }    
    ...
}

某些@Test使用mockMvc.perform()

我的看点是:

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

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

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

2 个答案:

答案 0 :(得分:8)

首先,有必要像Jason建议的那样使用webAppContextSetup:

@Autowired
private WebApplicationContext webApplicationContext;

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

此时应触发方面,但Mockito不会注射嘲笑。这是因为Spring AOP使用代理对象,并且正在将mocks注入此代理对象而不是代理对象。要解决此问题,需要打开对象并使用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;
}

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

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

答案 1 :(得分:0)

你可能正在使用Spring AOP,在这种情况下,bean必须是一个用于AOP工作的Spring bean,通过在控制器中不自动装配它完全绕过Spring AOP机制。

我认为修复应该只是注入控制器

 @Autowired
 @InjectMocks
 private UserController userController;