EasyMock 2.5 не работает для захвата более одного аргумента

Исключение появляется, когда я пытаюсь захватить более одного значения с помощью EasyMock.

easymock 2.5.2
easymockclassextension 2.2
mockito-all 1.8.5
hamcrest-all 1.1

Как решить это с помощью EasyMock?

Исходный код:

package easymock;

public class User {
    public static final int INT_VALUE = 1;
    public static final boolean BOOLEAN_VALUE = false;
    public static final String STRING_VALUE = "";
    private Service service;

    public void setService(Service service) {
        this.service = service;
    }

    public String userMethod(){
        return service.doSomething(INT_VALUE, BOOLEAN_VALUE, STRING_VALUE);
    }
}


package easymock;

public class Service {
    public String doSomething(Integer a, boolean b, String c){
        return null;
    }
}


package easymock;

import org.easymock.Capture;
import org.easymock.classextension.EasyMock;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;

import static org.easymock.EasyMock.anyBoolean;
import static org.easymock.EasyMock.anyObject;
import static org.easymock.classextension.EasyMock.capture;
import static org.easymock.classextension.EasyMock.expect;
import static org.easymock.classextension.EasyMock.replay;
import static org.easymock.classextension.EasyMock.verify;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class UserTest {

    private User user;
    private Service easyMockNiceMock;
    private Service mockitoMock;

    @Before
    public void setUp() throws Exception {
        user = new User();
        easyMockNiceMock = EasyMock.createNiceMock(Service.class);
        mockitoMock = mock(Service.class);
    }

    @Test
    public void easyMockTest() throws Exception {
        // given
        user.setService(easyMockNiceMock);

        Capture<Integer> integerCapture = new Capture<Integer>();
        Capture<Boolean> booleanCapture = new Capture<Boolean>();
        Capture<String> stringCapture = new Capture<String>();
        expect(easyMockNiceMock.doSomething(capture(integerCapture), capture(booleanCapture), capture(stringCapture))).andReturn("");
        replay(easyMockNiceMock);
        // when
        user.userMethod();
        // then
        verify(easyMockNiceMock);
        assertThat(integerCapture.getValue(), is(User.INT_VALUE));
        assertThat(booleanCapture.getValue(), is(User.BOOLEAN_VALUE));
        assertThat(stringCapture.getValue(), is(User.STRING_VALUE));
    }

    @Test
    public void easyMockTestValid() throws Exception {
        // given
        user.setService(easyMockNiceMock);

        Capture<Integer> integerCapture = new Capture<Integer>();
        expect(easyMockNiceMock.doSomething(capture(integerCapture), anyBoolean(), (String) anyObject())).andReturn("");
        replay(easyMockNiceMock);
        // when
        user.userMethod();
        // then
        verify(easyMockNiceMock);
        assertThat(integerCapture.getValue(), is(User.INT_VALUE));
    }

    @Test
    public void mockitoTest() throws Exception {
        // given
        user.setService(mockitoMock);

        ArgumentCaptor<Integer> integerArgumentCaptor = ArgumentCaptor.forClass(Integer.class);
        ArgumentCaptor<Boolean> booleanArgumentCaptor = ArgumentCaptor.forClass(Boolean.class);
        ArgumentCaptor<String> stringArgumentCaptor = ArgumentCaptor.forClass(String.class);

        when(mockitoMock.doSomething(integerArgumentCaptor.capture(), booleanArgumentCaptor.capture(), stringArgumentCaptor.capture())).thenReturn("");
        // when
        user.userMethod();
        // then
        assertThat(integerArgumentCaptor.getValue(), is(User.INT_VALUE));
        assertThat(booleanArgumentCaptor.getValue(), is(User.BOOLEAN_VALUE));
        assertThat(stringArgumentCaptor.getValue(), is(User.STRING_VALUE));
    }
}

Результаты теста:

  1. mockitoTest - всегда проходит
  2. easyMockTestValid — проходит, если запущен без easyMockTest
  3. easyMockTest - всегда сбой с сообщением:


java.lang.NullPointerException
        at easymock.UserTest.easyMockTest(UserTest.java:41)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
        at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
        at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
        at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
        at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:71)
        at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:202)
        at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

person Rrr    schedule 05.04.2012    source источник


Ответы (1)


Сначала вы используете разные версии расширений классов EasyMock и EasyMock. Я не думаю, что проблема в вашем случае, хотя я бы посоветовал вам иметь связные версии.

Во-вторых, я попробовал ваш код с версией 3.1 EasyMock, где расширение класса больше не нужно, и тесты прошли. Я не увидел ничего интересного в журнале изменений, хотя Генри мог что-то изменить в коде, чтобы ваш код заработал.

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

person Brice    schedule 06.04.2012
comment
Нет проблем с разными версиями EM и classextension. Баг был в самом easymock 2.5. В 3.1 все работает нормально, но я бы не рассматривал переход с 2.5 на 3.1 из-за проблем с совместимостью. - person Rrr; 09.04.2012
comment
ОК, круто, если вы решили проблему :) Что касается другой версии, в данном случае это может не быть проблемой, хотя многие инструменты выпускают компоненты, предназначенные для совместной работы, а затем с одной и той же версией. Также не могли бы вы разработать проблемы совместимости между 2.5 и 3.1, если вы не обновитесь сейчас, вас могут поймать позже, это может быть технический долг. - person Brice; 09.04.2012
comment
Да, я уже сталкивался с проблемами совместимости, взгляните на мой комментарий здесь stackoverflow.com/a/10049643/1063824 - person Rrr; 10.04.2012
comment
Собственно о classextension, он доступен на maven, ищите org.easymock:easymockclassextension:3.1. Хотя я настоятельно рекомендую вам обновить свой код и удалить эту зависимость, поскольку EasyMock и EasyMock CE объединились. Обратите внимание, что для проектов нормально изменять свой API или его часть с течением времени и выпусками, но сделать это безболезненно — настоящая проблема, дизайн API действительно сложен. И иногда вы попадаете в затруднительное положение, поэтому основные версии могут приводить к критическим изменениям API. В любом случае, удачи в предстоящей работе. - person Brice; 11.04.2012