EasyMock возвращает ноль

В настоящее время я работаю над некоторыми тестовыми примерами, в которых используется EasyMock. Мой примерный код выглядит так:

{
    dao = EasyMock.createNiceMock(Dao.class);

    initObj();
    EasyMock.replay(dao);
    // EasyMock.verify(dao);

    mapper = new Mapper();
    mapper.setDao(dao);
}
@Test
public void testmapper(){ 
    mapper.map();
}

public void initObj() {
    Obj o = new Obj();
    o.setX(2);
    EasyMock.expect(dao.findObj(1)).andReturn(o);
}

class Mapper {
    @Autowired
    private Dao dao;

    public Obj map(){
        Obj o = dao.findObj(1);
        System.out.println(o.getX());
        return o;
    }
    //getter and setter
}

если я на самом деле вызываю EasyMock.verify(dao);, он выдает

java.lang.AssertionError: 
  Expectation failure on verify:
    dao.findObj(1): expected: 1, actual: 0
    at org.easymock.internal.MocksControl.verify(MocksControl.java:183)
    at org.easymock.EasyMock.verify(EasyMock.java:2142)
    ...

и если я не вызову проверку, мой первый вызов внутри класса Mapper на моем Obj приведет к NPE. Я очень новичок в EasyMock и еще не мог найти причину, по которой он не возвращает Obj, который я создал в initObj. Любое просветление приветствуется. Я прочитал несколько вопросов по SO к этой теме, а также несколько простых руководств, но они мне не помогли.


person XtremeBaumer    schedule 13.07.2017    source источник
comment
Какая подпись у Obj#findObj? Это с Integer? (Не должно вызывать проблем, потому что первые n Integer экземпляров кэшируются, но кто знает?)   -  person D. Kovács    schedule 13.07.2017
comment
Obj#findObj доставляет пользовательский объект из базы данных. @khelwood, потому что сначала в моем коде не было вызова проверки   -  person XtremeBaumer    schedule 13.07.2017
comment
вопрос был нацелен не на тип возвращаемого значения, а на тип аргумента...   -  person D. Kovács    schedule 13.07.2017
comment
ааа, я передаю идентификатор, по которому будет выполняться поиск объекта. но, насколько я понимаю, EasyMock.expect(dao.findObj(1)).andReturn(o); ждет любого вызова, похожего на dao.findObj(1), и вместо этого возвращает объект, который я определил в andReturn(o);   -  person XtremeBaumer    schedule 13.07.2017
comment
Предоставленный класс Mapper не является допустимым java.   -  person Luciano van der Veekens    schedule 13.07.2017


Ответы (2)


verify должно быть после вашего теста. Итак, после mapper.map(). Он используется для проверки того, что все ожидаемые вызовы были сделаны. Так что имеет смысл, что это происходит в конце.

Тогда абсолютно невозможно получить NPE с кодом, который вы предоставляете. Если у вас нет проблем с getX и setX. Вот моя версия вашего кода. Это работает отлично.

public class MyTest {

    private final Dao dao;
    private final Mapper mapper;

    {
        dao = EasyMock.createNiceMock(Dao.class);

        initObj();
        EasyMock.replay(dao);
        // EasyMock.verify(dao);

        mapper = new Mapper();
        mapper.setDao(dao);
    }

    @Test
    public void testmapper(){
        mapper.map();
        EasyMock.verify(dao);
    }

    public void initObj() {
        Obj o = new Obj();
        o.setX(2);
        EasyMock.expect(dao.findObj(1)).andReturn(o);
    }

    class Mapper {
        private Dao dao;

        public Obj map(){
            Obj o = dao.findObj(1);
            System.out.println(o.getX());
            return o;
        }

        public void setDao(Dao dao) {
            this.dao = dao;
        }
    }

    class Obj {
        private int x;

        public int getX() {
            return x;
        }

        public void setX(int x) {
            this.x = x;
        }
    }

    interface Dao {
        Obj findObj(int i);
    }
}
person Henri    schedule 16.07.2017

Я нашел решение своей проблемы. В моем методе initObj() я также должен определить количество вызовов для ожидаемого поведения следующим образом:

public void initObj() {
    Obj o = new Obj();
    o.setX(2);
    EasyMock.expect(dao.findObj(1)).andReturn(o).times(1);
}

Что-то я до сих пор не понимаю, как это может работать без times(1). У меня есть пример кода от коллеги, где он работает, просто используя EasyMock.expect(dao.findObj(1)).andReturn(o);

person XtremeBaumer    schedule 13.07.2017
comment
Нет. Вам не нужно указывать times(1). По умолчанию EasyMock будет считать один вызов при вызове andReturn - person Henri; 17.07.2017
comment
@ Генри, моя точная проблема заключалась в том, что я неправильно понял аннотации @Before и @After, так как думал, что они будут вызываться только один раз, а не перед каждым тестом. также не каждый метод, который я указал, как ожидалось, в моем @Before, вызывался в каждом тесте, и поэтому EasyMock.verify(dao); также не прошел. однако теперь у меня есть работающий код, и я научился на своих ошибках - person XtremeBaumer; 19.07.2017