Может ли Мокито заглушить метод без учета аргумента?

java unit-testing mocking mockito

195606 просмотра

4 ответа

24919 Репутация автора

Я пытаюсь протестировать некоторый унаследованный код, используя Mockito.

Я хочу заглушить, FooDaoчто используется в производстве следующим образом:

foo = fooDao.getBar(new Bazoo());

Я могу написать:

when(fooDao.getBar(new Bazoo())).thenReturn(myFoo);

Но очевидная проблема заключается в том, что getBar()никогда не вызывается с тем же Bazooобъектом, для которого я обозначил метод. (Прокляни этого newоператора!)

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

Автор: Eric Wilson Источник Размещён: 11.05.2011 07:35

Ответы (4)


13 плюса

6035 Репутация автора

http://site.mockito.org/mockito/docs/1.10.19/org/mockito/Matchers.html

anyObject() должно соответствовать вашим потребностям.

Также вы всегда можете рассмотреть возможность реализации hashCode()и equals()для Bazooкласса. Это заставит ваш пример кода работать так, как вы хотите.

Автор: Buhb Размещён: 11.05.2011 07:42

434 плюса

284337 Репутация автора

Решение
when(
  fooDao.getBar(
    any(Bazoo.class)
  )
).thenReturn(myFoo);

или (чтобы избежать nulls):

when(
  fooDao.getBar(
    (Bazoo)notNull()
  )
).thenReturn(myFoo);

Не забудьте импортировать совпадения (доступно много других):

Для Mockito 2.1.0 и новее:

import static org.mockito.ArgumentMatchers.*;

Для более старых версий:

import static org.mockito.Matchers.*;
Автор: Tomasz Nurkiewicz Размещён: 11.05.2011 07:42

15 плюса

0 Репутация автора

Используйте как это:

when(
  fooDao.getBar(
    Matchers.<Bazoo>any()
  )
).thenReturn(myFoo);

Прежде чем вам нужно импортировать Mockito.Matchers

Автор: user3975308 Размещён: 21.11.2014 05:01

0 плюса

7719 Репутация автора

Другой вариант - положиться на старый добрый equalsметод моды . Пока аргумент в whenmock equalsаргумент в тестируемом коде, Mockito будет соответствовать макету.

Вот пример.

public class MyPojo {

    public MyPojo( String someField ) {
        this.someField = someField;
    }

    private String someField;

    @Override
    public boolean equals( Object o ) {
        if ( this == o ) return true;
        if ( o == null || getClass() != o.getClass() ) return false;
        MyPojo myPojo = ( MyPojo ) o;
        return someField.equals( myPojo.someField );
    }

}

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

when(fooDao.getBar(new MyPojo(expectedSomeField))).thenReturn(myFoo);

Плюсы: это более явно, чем anyсовпадения. Как рецензент кода, я внимательно слежу за anyтем, что пишут младшие разработчики кода, поскольку он просматривает логику своего кода, чтобы сгенерировать соответствующий передаваемый объект.

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

Другой возможный подход заключается в использовании Answerобъекта Mockito, который можно использовать с whenметодом. Answerпозволяет вам перехватить реальный вызов, проверить входной аргумент и вернуть фиктивный объект. В приведенном ниже примере я использую, anyчтобы перехватить любой запрос к методу. Но затем в Answerлямбде я могу дополнительно проверить аргумент Базо ... возможно, чтобы убедиться, что ему был передан правильный идентификатор. Я предпочитаю это anyсамому себе, чтобы по крайней мере какая-то проверка была сделана по аргументу.

    Bar mockBar = //generate mock Bar.

    when(fooDao.getBar(any(Bazo.class))
    .thenAnswer(  ( InvocationOnMock invocationOnMock) -> {
        Bazo actualBazo = invocationOnMock.getArgument( 0 );

        //inspect the actualBazo here and thrw exception if it does not meet your testing requirements.
        return mockBar;
    } );

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

Автор: Jose Martinez Размещён: 29.10.2019 01:43
Вопросы из категории :
32x32