Java 如何在easymock中模拟一个返回其参数之一的方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2667172/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I mock a method in easymock that shall return one of its parameters?
提问by Jan
public Object doSomething(Object o);
which I want to mock. It should just return its parameter. I tried:
public Object doSomething(Object o);
我想嘲笑。它应该只返回它的参数。我试过:
Capture<Object> copyCaptcher = new Capture<Object>();
expect(mock.doSomething(capture(copyCaptcher)))
.andReturn(copyCatcher.getValue());
but without success, I get just an AssertionError as java.lang.AssertionError: Nothing captured yet
. Any ideas?
但没有成功,我只得到一个 AssertionError 作为java.lang.AssertionError: Nothing captured yet
. 有任何想法吗?
采纳答案by rems
I was looking for the same behavior, and finally wrote the following :
我正在寻找相同的行为,最后写了以下内容:
import org.easymock.EasyMock; import org.easymock.IAnswer; /** * Enable a Captured argument to be answered to an Expectation. * For example, the Factory interface defines the following * <pre> * CharSequence encode(final CharSequence data); * </pre> * For test purpose, we don't need to implement this method, thus it should be mocked. * <pre> * final Factory 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> * Created on 22 juin 2010. * @author Remi Fouilloux * */ public class ArgumentAnswer<T> implements IAnswer<T> { private final int argumentOffset; public ArgumentAnswer() { this(0); } public ArgumentAnswer(int offset) { this.argumentOffset = offset; } /** * {@inheritDoc} */ @SuppressWarnings("unchecked") public T answer() throws Throwable { final Object[] args = EasyMock.getCurrentArguments(); if (args.length < (argumentOffset + 1)) { throw new IllegalArgumentException("There is no argument at offset " + argumentOffset); } return (T) args[argumentOffset]; } }
I wrote a quick "how to" in the javadoc of the class.
我在类的 javadoc 中写了一个快速的“操作方法”。
Hope this helps.
希望这可以帮助。
回答by drekka
Um, if I understand your question correctly I think you may be over complicating it.
嗯,如果我正确理解你的问题,我认为你可能把它复杂化了。
Object someObject = .... ;
expect(mock.doSomething(someObject)).andReturn(someObject);
Object someObject = .... ;
expect(mock.doSomething(someObject)).andReturn(someObject);
Should work just fine. Remember you are supplying both the expected parameter and returne value. So using the same object in both works.
应该工作得很好。请记住,您同时提供了预期参数和返回值。所以在两个作品中使用相同的对象。
回答by does_the_trick
Well, the easiest way would be to just use the Capture in the IAnswer implementation... when doing this inline you have to declare it final
of course.
好吧,最简单的方法是只在 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)
This is probably the most exact way, without relying on some context information. This does the trick for me every time.
这可能是最准确的方式,不依赖于某些上下文信息。这每次都对我有用。
回答by thetoolman
Captures are for testing the values passed to the mock afterwards. If you only need a mock to return a parameter (or some value calculated from the parameter), you just need to implement IAnswer.
捕获用于测试之后传递给模拟的值。如果你只需要一个模拟来返回一个参数(或者一些从参数计算出来的值),你只需要实现 IAnswer。
See "Remi Fouilloux"s implementation if you want a reusable way of passing paramter X back, but ignore his use of Capture in the example.
如果您想要一种将参数 X 传回的可重用方式,请参阅“Remi Fouilloux”的实现,但忽略他在示例中使用 Capture。
If you just want to inline it like "does_the_trick"s example, again, the Capture is a red herring here. Here is the simplified version:
如果你只是想像“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)
回答by Marco Baumeler
Based on @does_the_trick and using lambdas, you can now write the following:
基于@does_the_trick 并使用 lambdas,您现在可以编写以下内容:
MyService mock = EasyMock.createMock(MyService.class);
final Capture<ParamAndReturnType> myCapture = EasyMock.newCapture();
expect(mock.someMethod(capture(myCapture))).andAnswer(() -> myCapture.getValue());
or without capture as @thetoolman suggested
或者不按照@thetoolman 的建议进行捕获
expect(mock.someMethod(capture(myCapture)))
.andAnswer(() -> (ParamAndReturnType)EasyMock.getCurrentArguments()[0]);