How to clean up mocks in spring tests when using Mockito

前端 未结 4 2008
孤城傲影
孤城傲影 2020-12-25 11:30

I\'m pretty new to Mockito and have some trouble with clean up.

I used to use JMock2 for unit tests. As far as I know, JMock2 preserves the expectations and other mo

4条回答
  •  一整个雨季
    2020-12-25 12:14

    Spring based test is hard to make fast and independed (as @Brice wrote). Here is a litle utility method for reset all mocks (you have to call it manually in every @Before method):

    import org.mockito.Mockito;
    import org.springframework.aop.framework.Advised;
    import org.springframework.aop.support.AopUtils;
    import org.springframework.context.ApplicationContext;
    
    
    public class MyTest {
        public void resetAll(ApplicationContext applicationContext) throws Exception {
            for (String name : applicationContext.getBeanDefinitionNames()) {
                Object bean = applicationContext.getBean(name);
                if (AopUtils.isAopProxy(bean) && bean instanceof Advised) {
                    bean = ((Advised)bean).getTargetSource().getTarget();
                }
                if (Mockito.mockingDetails(bean).isMock()) {
                    Mockito.reset(bean);
                }
            }
        }
    }
    

    As you see there is an iteration for all beans, check whether bean is mock or not, and reset the mock. I pay especially attention on call AopUtils.isAopProxy and ((Advised)bean).getTargetSource().getTarget(). If you bean contains an @Transactional annotation the mock of this bean always wrapped by spring into proxy object, so to reset or verify this mock you should unwrap it first. Otherwise you will get a UnfinishedVerificationException which can arise in different tests from time to time.

    In my case AopUtils.isAopProxy is enough. But there are also AopUtils.isCglibProxy and AopUtils.isJdkDynamicProxy if you get troubles with proxying.

    mockito is 1.10.19 spring-test is 3.2.2.RELEASE

提交回复
热议问题