Как использовать thenAnswer с методом, который возвращает void - PullRequest
1 голос
/ 06 января 2012

Я хочу провести модульное тестирование следующим методом

public void addRecord(Record record)  
{  
   Myclass newObj = new Mycalss();  
   // It creates newObj object, set some values using record object.  
   // and it adds the newObj in daatbase.
   dataReqDao.persist(newObj);
}    

Я смоделировал метод dataReqDao.persist, но как я могу проверить, копируются ли правильные значения в объект newObj?Я хочу получить объект newObj.

Я думаю, thenAnswer будет подходящим методом для извлечения newObj, т.е. аргументов метода, но не знаю, как использовать этот метод, который возвращает void.

Обновление:
Я пытался

doAnswer(new Answer<Myclass>() {
              public Myclass answer(InvocationOnMock invocation) {
                  Object[] args = invocation.getArguments();
                  return (Myclass)args[0];
              }

        }).when(dataReqDao.persist(any(Myclass.class)));

РЕДАКТИРОВАТЬ:
Это должно быть (Спасибо Дэвид)

 doAnswer(new Answer<Myclass>() {
                  public Myclass answer(InvocationOnMock invocation) {
                      Object[] args = invocation.getArguments();
                      return (Myclass)args[0];
                  }

            }).when(dataReqDao).persist(any(Myclass.class));

Ответы [ 3 ]

5 голосов
/ 06 января 2012

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

Например, следующим образом:

ArgumentCaptor<Myclass> c = ArgumentCaptor.forClass(Myclass.class);
verify(dateReqDao).persist(c.capture());
Myclass newObj = c.getValue();

... // Validate newObj
1 голос
/ 10 апреля 2015

Вам нужно сделать это с помощью thenAnswer (или затем , что я лично предпочитаю), чтобы вы могли утверждать / проверять значения во время вызова метода в методе.

 when(dataReqDao.persist(newObj)).then(new Answer<Void>() {
        @Override
        public Void answer(final InvocationOnMock invocation) {
            Myclass newObjActual = (Myclass) invocation.getArguments()[0];

            // Control
            assertEquals(..., newObjActual.getX());
            assertEquals(..., newObjActual.getY());
            return null;
        }
    });

 // Run Test
 x.addRecord(record);

Вот подробное объяснение: https://akcasoy.wordpress.com/2015/04/09/the-power-of-thenanswer/ (Вариант использования 2)

ArgumentCaptor не проверяет умным способом. Когда вы меняете свой метод следующим образом:

public void addRecord(Record record)  
{  
   Myclass newObj = new Mycalss();  
   dataReqDao.persist(newObj);

   // first persist, than set attributes
   newObj.setX(..);
}  

.. ваш тест с Captor все еще выполняется, но он не пройден. Поскольку ArgumentCaptor не захватывает это состояние объекта во время вызова, а только objectId, для captor не имеет значения, устанавливаете ли вы свои атрибуты до или после вызова dao. Тем не менее, хороший тест должен проваливаться при каждом функциональном изменении. Вот моя статья именно об этом случае:

https://akcasoy.wordpress.com/2015/02/03/how-to-ensure-quality-of-junit-tests/ (вышеупомянутая заглушка с , тогда является более подходящим подходом, чем подход с InOrder)

0 голосов
/ 18 января 2012
Myclass newObj = new Myclass();  

Эта линия беспокоит меня. Если вы используете внедрение зависимостей, ваша фабрика должна отправить вам экземпляр этого объекта. Затем, когда вы создаете свои модульные тесты, вы можете отправить фабрику тестов в фиктивный экземпляр MyClass, к которому у модульного теста также может быть доступ. Затем вы можете использовать захватчик Axtavt, чтобы увидеть, действительно ли он сделал то, что должен был сделать. В модульном тесте нет ничего плохого в том, как вы это сделали, просто что any () является слабым, учитывая, что вы знаете, что оно проходит в объекте этого типа - в тесте вы хотите знать, является ли объект это тот, который вы намеревались и не был изменен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...