при запуске теста mockito происходит исключение WrongTypeOfReturnValue


96

Детали ошибки:

org.mockito.exceptions.misusing.WrongTypeOfReturnValue: 
Boolean cannot be returned by updateItemAttributesByJuId()
updateItemAttributesByJuId() should return ResultRich
This exception might occur in wrongly written multi-threaded tests.
Please refer to Mockito FAQ on limitations of concurrency testing.

мой код:

@InjectMocks
protected ItemArrangeManager arrangeManagerSpy = spy(new ItemArrangeManagerImpl());
@Mock
protected JuItemWriteService juItemWriteService;

when(arrangeManagerSpy
    .updateItemAttributes(mapCaptor.capture(), eq(juId), eq(itemTO.getSellerId())))
    .thenReturn(false);

Как вы можете видеть, я звоню whenна updateItemAttributes(что делает возвращающие boolean) не на updateItemAttributesByJuId.

  1. Почему Mockito пытается вернуть booleanиз updateItemAttributesByJuId?
  2. Как это исправить?

Ответы:


199

Согласно https://groups.google.com/forum/?fromgroups#!topic/mockito/9WUvkhZUy90 , вам следует перефразировать свой

when(bar.getFoo()).thenReturn(fooBar)

к

doReturn(fooBar).when(bar).getFoo()

3
Это отличный совет. У меня также возникла эта проблема при тестировании @Repositoryметода Spring DAO с @Aspect . если да when(someDao.someMethod()).thenReturn(List<xxx>), то получу исключение WrongTypeOfReturnValue. Благодаря отладке я вижу, что someMethodметод действительно был вызван в приведенном выше заявлении и запускает Around Advice и возвращает, nullно Mockito ожидает List<xxx>.
LeOn - Хан Ли

У меня получилось. Обригадо!
Саксофонист

Отличный ответ. Это спас мой день.
user3198259

Работал и у меня! Благодарность! Хотя я не полностью понял объяснение в предоставленной ссылке.
georgeliatsos

40

Другая причина подобного сообщения об ошибке - попытка имитировать finalметод. Не следует пытаться высмеивать окончательные методы (см последний метод насмешки ).

Я также столкнулся с ошибкой в ​​многопоточном тесте. Ответ gna работал в этом случае.


20

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

Boolean fooBar;
when(bar.getFoo()).thenReturn(fooBar);

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

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

doReturn(fooBar).when(bar).getFoo();

Спасибо. Похоже, что с классами данных Kotlin существует та же проблема, что и с полями, и ваше решение решило ее!
Мохсен Миросейни

6

Для меня это означало, что я выполнял это:

a = Mockito.mock(SomeClass.class);
b = new RealClass();
when(b.method1(a)).thenReturn(c); 
// within this method1, it calls param1.method2() -- note, b is not a spy or mock

Так что же происходит, что Mockito обнаруживал , что a.method2()в настоящее время называется, и говорил мне , что я не мог вернуться cиз a.method2()которых является неправильным.

Исправление: используйте doReturn(c).when(b).method1(a)синтаксис стиля (вместо when(b.method1(a)).thenReturn(c);), который поможет вам более кратко и быстро обнаружить скрытую ошибку.

Или в этом конкретном случае, после этого он начал показывать более точное «NotAMockException», и я изменил его, чтобы больше не пытаться установить возвращаемое значение из немодельного объекта.


1
Та же ошибка, что и я. Я издевался над методом, используемым в method1, выполнил и получил это исключение. Это было решено, как только я удалил этот код.
Praveen.883

5

У меня недавно была эта проблема. Проблема заключалась в том, что метод, который я пытался имитировать, не имел модификатора доступа. Добавление паблика решило проблему.


5

У меня была эта ошибка, потому что в моем тесте у меня было два ожидания: одно от макета, а другое от конкретного типа

MyClass cls = new MyClass();
MyClass cls2 = Mockito.mock(Myclass.class);
when(foo.bar(cls)).thenReturn(); // cls is not actually a mock
when(foo.baz(cls2)).thenReturn();

Я исправил это, изменив cls на макет


4

В моем случае проблема была вызвана попыткой имитировать статический метод и забыть вызвать mockStaticкласс. Также я забыл включить класс в@PrepareForTest()


2

Если вы используете аннотации, возможно, вам нужно использовать @Mock вместо @InjectMocks. Потому что @InjectMocks вместе работает как @Spy и @Mock. А @Spy отслеживает недавно выполненные методы, и вы можете почувствовать, что возвращаются / подкладываются неверные данные.


2
" @InjectMocksработает как @Spyи @Mockвместе". <- мне это кажется неправильным. Откуда вы это слышали?
Этьен Мирет

2

В моем случае я использовал оба @RunWith(MockitoJUnitRunner.class)и MockitoAnnotations.initMocks(this). Когда я удалил, MockitoAnnotations.initMocks(this)все заработало правильно.


1

Ошибка:

org.mockito.exceptions.misusing.WrongTypeOfReturnValue:
String не может быть возвращен с помощью size ()
size () должен возвращать int
***
Если вы не уверены, почему вы получаете указанную выше ошибку, прочтите.
Из-за природы синтаксиса выше проблема может возникнуть по следующим причинам:
1. Это исключение может возникнуть в неправильно написанных многопоточных
тестах.
Пожалуйста, обратитесь к Mockito FAQ об ограничениях тестирования параллелизма.
2. Заглушка шпиона выполняется с использованием синтаксиса when (spy.foo ()). Then (). Это безопаснее
окурок шпионов -
- с doReturn | семья Throw () методов. Подробнее в документации по
методу Mockito.spy ().

Фактический код:

@RunWith(PowerMockRunner.class)
@PrepareForTest({ Object.class, ByteString.class})

@Mock
private ByteString mockByteString;

String testData = “dsfgdshf”;
PowerMockito.when(mockByteString.toStringUtf8()).thenReturn(testData); 
// throws above given exception

Решение для устранения этой проблемы:

1-й Удалите аннотацию «@Mock».

private ByteString mockByteString;

2-е добавление PowerMockito.mock

mockByteString = PowerMockito.mock(ByteString.class);

1

Недавно я столкнулся с этой проблемой, когда издевался над функцией в классе данных Kotlin . По неизвестной причине один из моих тестовых прогонов оказался в зависшем состоянии. Когда я снова запустил тесты, некоторые из моих тестов, которые были пройдены ранее, начали давать сбой с WrongTypeOfReturnValueисключением.

Я убедился, что использую, org.mockito:mockito-inlineчтобы избежать проблем с финальными классами (упомянутыми Arvidaa), но проблема осталась. Для меня это решило убить процесс и перезапустить Android Studio . Это прервало мой замороженный тестовый прогон, и следующие тестовые прогоны прошли без проблем.


1

Отсутствует @MockBean на bean-компоненте, над которым вы хотите издеваться


1

У WrongTypeOfReturnValueменя возникла эта проблема, потому что я издевался над методом, возвращающим java.util.Optional;a, com.google.common.base.Optional;из-за того, что мой форматировщик автоматически добавляет недостающие импорты.

Mockito просто говорил мне, что «метод something () должен возвращать Optional» ...


1

В моем случае bean-компонент был инициализирован с использованием аннотации @Autowired вместо @MockBean

Таким образом, издевательство над DAO и службами вызывает такое исключение.


1
Да, в моем случае тест службы приложения Spring-Boot, MockBean должен использоваться при имитации Bean. Благодарность!
Исаак Филипп

1

Для меня проблема заключалась в многопоточных тестах, которые выполняли заглушку / проверку общих моков. Это привело к случайному выбрасыванию WrongTypeOfReturnValueисключения.

Это неправильно написанный тест с использованием Mockito. К мокам нельзя обращаться из нескольких потоков.

Решением было сделать mocks локальными для каждого теста.


1

TL; DR Если некоторые аргументы в вашем тесте есть null, обязательно имитируйте вызов параметра с помощью isNull()вместо anyXXX().


Я получил эту ошибку при обновлении Spring boot 1.5.x до 2.1.x. Spring boot поставляется с собственным Mockito, который теперь также обновлен до 2.x (см., Например, « Зависимости Spring boot 2.1.2» ).

Mockito изменилось поведение для anyXXX()метода, где XXXнаходится String,Long и т.д. Вот является Javadoc из anyLong():

Начиная с Mockito 2.1.0, допускаются только значения Long, поэтому nullбольше не является допустимым значением Поскольку примитивные оболочки допускают значение NULL, предлагаемый API для сопоставления null оболочки будет #isNull(). Мы чувствовали, что это изменение сделает систему тестирования намного безопаснее, чем это было в Mockito 1.x.

Я предлагаю вам отладить до того момента, когда ваш макет будет вызван, и проверьте, является ли хотя бы один аргументnull . В этом случае убедитесь, что вы подготовить макет с isNull()вместо например anyLong().

Итак, это:

when(MockedClass.method(anyString());

становится:

when(MockedClass.method(isNull());

-1

Это мой случай:

//given
ObjectA a = new ObjectA();
ObjectB b = mock(ObjectB.class);
when(b.call()).thenReturn(a);

Target target = spy(new Target());
doReturn(b).when(target).method1();

//when
String result = target.method2();

Затем я получаю такую ​​ошибку:

org.mockito.exceptions.misusing.WrongTypeOfReturnValue: 
ObjectB$$EnhancerByMockitoWithCGLIB$$2eaf7d1d cannot be returned by method2()
method2() should return String

Вы можете догадаться?

Проблема в том, что Target.method1 () - статический метод. Мокито полностью предупреждает меня о другом.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.