32

public Object doSomething(Object o);我想嘲笑它。它应该只返回它的参数。我试过:

Capture<Object> copyCaptcher = new Capture<Object>();
expect(mock.doSomething(capture(copyCaptcher)))
        .andReturn(copyCatcher.getValue());

但没有成功,我只得到一个 AssertionError 作为java.lang.AssertionError: Nothing captured yet. 有任何想法吗?

4

5 回答 5

29

好吧,最简单的方法是在 IAnswer 实现中使用 Capture ......当你这样做时,你final当然必须声明它。

MyService mock = createMock(MyService.class);

final Capture<ParamAndReturnType> myCapture = new Capture<ParamAndReturnType>();
expect(mock.someMethod(capture(myCapture))).andAnswer(
    new IAnswer<ParamAndReturnType>() {
        @Override
        public ParamAndReturnType answer() throws Throwable {
            return myCapture.getValue();
        }
    }
);
replay(mock)

这可能是最准确的方式,而不依赖于一些上下文信息。这每次都对我有用。

于 2011-10-17T16:41:16.893 回答
19

我一直在寻找相同的行为,最后写了以下内容:

导入 org.easymock.EasyMock;
导入 org.easymock.IAnswer;

/**
 * 使捕获的参数能够回答期望。
 * 例如Factory接口定义如下
 * <前>
 * CharSequence 编码(最终的 CharSequence 数据);
 * </pre>
 * 出于测试目的,我们不需要实现此方法,因此应该对其进行模拟。
 * <前>
 * 最终工厂 factory = mocks.createMock("factory", Factory.class);
 * final ArgumentAnswer<CharSequence> parrot = new ArgumentAnswer<CharSequence>();
 * EasyMock.expect(factory.encode(EasyMock.capture(new Capture<CharSequence>()))).andAnswer(parrot).anyTimes();
 * </pre>
 * 创建于 2010 年 6 月 22 日。
 * @作者雷米·弗卢克斯
 *
 */
公共类 ArgumentAnswer<T> 实现 IAnswer<T> {

    私有最终 int 参数偏移;

    公共 ArgumentAnswer() {
        这(0);
    }

    公共 ArgumentAnswer(int offset) {
        this.argumentOffset = 偏移量;
    }

    /**
     * {@inheritDoc}
     */
    @SuppressWarnings("未选中")
    public T answer() 抛出 Throwable {
        final Object[] args = EasyMock.getCurrentArguments();
        if (args.length < (argumentOffset + 1)) {
            throw new IllegalArgumentException("偏移处没有参数" + argumentOffset);
        }
        返回 (T) args[argumentOffset];
    }

}

我在课堂的 javadoc 中写了一个快速的“如何做”。

希望这可以帮助。

于 2010-06-22T10:34:27.407 回答
17

捕获用于测试之后传递给模拟的值。如果你只需要一个mock来返回一个参数(或从参数计算的一些值),你只需要实现IAnswer。

如果您想要一种可重用的方式将参数 X 传回,请参阅“Remi Fouilloux”的实现,但请忽略他在示例中对 Capture 的使用。

如果你只是想像“does_the_trick”的例子一样内联它,Capture 在这里是一个红鲱鱼。这是简化版:

MyService mock = createMock(MyService.class);
expect(mock.someMethod(anyObject(), anyObject()).andAnswer(
    new IAnswer<ReturnType>() {
        @Override
        public ReturnType answer() throws Throwable {
            // you could do work here to return something different if you needed.
            return (ReturnType) EasyMock.getCurrentArguments()[0]; 
        }
    }
);
replay(mock)
于 2012-01-17T20:22:17.920 回答
9

基于@does_the_trick 并使用 lambda,您现在可以编写以下代码:

MyService mock = EasyMock.createMock(MyService.class);

final Capture<ParamAndReturnType> myCapture = EasyMock.newCapture();
expect(mock.someMethod(capture(myCapture))).andAnswer(() -> myCapture.getValue());

或者像@thetoolman 建议的那样不捕获

expect(mock.someMethod(capture(myCapture)))
.andAnswer(() -> (ParamAndReturnType)EasyMock.getCurrentArguments()[0]);
于 2015-01-16T21:38:17.990 回答
2

嗯,如果我正确理解你的问题,我认为你可能过于复杂了。

Object someObject = .... ;
expect(mock.doSomething(someObject)).andReturn(someObject);

应该工作得很好。请记住,您同时提供了预期的参数和返回值。所以在两部作品中使用相同的对象。

于 2010-04-19T12:14:51.170 回答