Подтвердить что ты не робот

Как я могу издеваться над методом в easymock, который должен вернуть один из его параметров?

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. Любые идеи?

4b9b3361

Ответ 1

Я искал такое же поведение и, наконец, написал следующее:

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];
    }

}

Я написал быстрый "как" в javadoc класса.

Надеюсь, что это поможет.

Ответ 2

Ну, самый простой способ - просто использовать Capture в реализации IAnswer... когда вы делаете это inline, вы должны, конечно, объявить его 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)

Это, вероятно, самый точный способ, не полагаясь на какую-либо контекстную информацию. Это делает трюк для меня каждый раз.

Ответ 3

Захваты предназначены для тестирования значений, переданных впоследствии макету. Если вам нужен только макет, чтобы вернуть параметр (или некоторое значение, вычисленное из параметра), вам просто нужно реализовать IAnswer.

См. "Реми Фуулу", если вы хотите использовать многоразовый способ передать параметр X назад, но проигнорируйте его использование Capture в этом примере.

Если вы просто хотите встроить его в пример "do_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)

Ответ 4

Основываясь на @does_the_trick и используя lambdas, вы можете написать следующее:

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]);

Ответ 5

Ум, если я правильно понимаю ваш вопрос, я думаю, что вы, возможно, слишком усложняете его.

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

Должно работать нормально. Помните, что вы поставляете как ожидаемый параметр, так и значение returne. Поэтому использование одного и того же объекта в обеих работах.