首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Mockito -监视真实对象调用原始方法

Mockito -监视真实对象调用原始方法
EN

Stack Overflow用户
提问于 2012-02-02 17:47:08
回答 2查看 35.2K关注 0票数 20

想象一下下面的代码:

代码语言:javascript
复制
List list = .....
List spy = spy(list);
doThrow(new NullpointerException()).when(spy).get(0);

doThrow(....)执行list.get(0) --这没有任何意义。我想在这里定义模拟行为,而不是调用方法……我是不是遗漏了什么?

编辑:列表由CGLIB装饰。当我删除CGLIB代理时,Mockito可以正常工作。你知道如何在使用CGLIB代理时解决这样的问题吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-02-09 00:28:13

代码语言:javascript
复制
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.spy;

import java.lang.reflect.Method;

import org.junit.Test;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class MockitoSpyTest {

    @Test
    public void execTest() {

        System.out.println("*** TEST 1 ***");
        System.out.println("Test on unmodified object");
        MySet ms = new MySetImpl();
        ms.set("test value");
        System.out.println("Set contains: " + ms.get());

        // decorate ms1 with easymock
        System.out.println("\n*** TEST 2 ***");
        MySet spyMs = spy(ms);
        doThrow(new NullPointerException("my test nullpointer")).when(spyMs).get();
        System.out.println("Test decorated object with SPY");
        spyMs.set("test value");
        try {
            System.out.println("Set contains: " + spyMs.get());
        } catch (NullPointerException e) {
            System.out.println("NullPointerException - as expected");
        }

        // Enhance call with CGLIB
        System.out.println("\n*** TEST 3 ***");
        System.out.println("Test on CGLIB decorated object");
        Enhancer enc = new Enhancer();
        enc.setSuperclass(MySetImpl.class);
        enc.setInterfaces(new Class[] { MySet.class });
        enc.setCallback(new MethodInterceptor() {

            @Override
            public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
                if ("get".equals(method.getName())) {
                    System.out.println("CGLIB decorated GET call");
                }
                return proxy.invokeSuper(obj, args);
            }
        });
        MySet ms1 = (MySet) enc.create();
        ms1.set("test value");
        System.out.println("Set contains: " + ms1.get());

        // decorate ms1 with easymock
        System.out.println("\n*** TEST 4 ***");
        System.out.println("Test on CGLIB decorated object with SPY");
        MySet spyMs1 = spy(ms1);
        doThrow(new NullPointerException("my test nullpointer")).when(spyMs1).get();
        spyMs1.set("test value");
        System.out.println("Set contains: " + spyMs1.get());
    }

    public interface MySet {
        void set(String val);

        String get();
    }

    public static class MySetImpl implements MySet {
        String val;

        public void set(String val) {
            this.val = val;
            System.out.println("Original SET call:" + val);
        }

        public String get() {

            System.out.println("Original GET call:" + val);
            return val;
        }

    }
}

上面的示例生成输出:

代码语言:javascript
复制
*** TEST 1 ***
Test on unmodified object
Original SET call:test value
Original GET call:test value
Set contains: test value

*** TEST 2 ***
Test decorated object with SPY
Original SET call:test value
NullPointerException - as expected

*** TEST 3 ***
Test on CGLIB decorated object
Original SET call:test value
CGLIB decorated GET call
Original GET call:test value
Set contains: test value

*** TEST 4 ***
Test on CGLIB decorated object with SPY
CGLIB decorated GET call
Original GET call:test value
Original SET call:test value
CGLIB decorated GET call
Original GET call:test value
Set contains: test value

现在TEST 2TEST 4应该在get调用上抛出NullPointerException -基于mockito spy:doThrow(new NullPointerException("my test nullpointer")).when(spyMs1).get();

“测试4”没有抛出预期的异常,因为它已经被CGLIB装饰了-我们还可以在控制台上看到CGLIb调用正在执行:GLIB decorated GET call,而不是在spy对象上调用。当结合使用Spring AOP和CGLIB代理时,也可以达到同样的效果。

票数 8
EN

Stack Overflow用户

发布于 2012-02-08 11:16:31

代码语言:javascript
复制
Mockito.doThrow(new NullpointerException()).when(spy).get(0);

我认为这里的问题是你正在尝试做一个部分模拟,所以你必须在你的测试类上有注解:

代码语言:javascript
复制
@PrepareForTest(List.class)

这可能会也可能不会起作用。在我测试异常处理的代码中,我总是在完全模拟的对象上执行异常处理,而不是部分模拟的对象。此外,我在部分模拟时广泛使用了PowerMockito,所以库可能会做你需要的事情。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9110125

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档