ketika saya menjalankan uji mockito terjadi Pengecualian WrongTypeOfReturnValue

96

Detail kesalahan:

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.

kode saya:

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

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

Seperti yang Anda lihat, saya menelepon whenpada updateItemAttributes(yang tidak kembalinya boolean) tidak di updateItemAttributesByJuId.

  1. Mengapa Mockito mencoba mengembalikan booleandari updateItemAttributesByJuId?
  2. Bagaimana ini bisa diperbaiki?
bel angin bingung
sumber

Jawaban:

200

Menurut https://groups.google.com/forum/?fromgroups#!topic/mockito/9WUvkhZUy90 , Anda harus mengubah

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

untuk

doReturn(fooBar).when(bar).getFoo()
gna
sumber
3
Ini tip yang bagus. Saya juga mengalami masalah ini saat menguji beberapa @Repositorymetode Spring DAO dengan @Aspect . jika ya when(someDao.someMethod()).thenReturn(List<xxx>), saya mendapat pengecualian WrongTypeOfReturnValue ini. Melalui debug, saya dapat melihat bahwa someMethodmetode ini sebenarnya dipanggil dalam pernyataan di atas dan memicu Sekitar Advice dan mengembalikan nulltetapi Mockito mengharapkan List<xxx>.
LeOn - Han Li
Berhasil untuk saya. Obrigado!
Pemain saksofon
Jawaban Luar Biasa. Ini Menyelamatkan hariku.
user3198259
Bekerja juga untuk saya! Terima kasih! Meskipun, saya tidak sepenuhnya memahami penjelasan di tautan yang disediakan.
georgeliatsos
40

Alasan lain untuk pesan kesalahan serupa adalah mencoba meniru finalmetode. Seseorang tidak boleh mencoba untuk mengejek metode akhir (lihat mengejek metode terakhir ).

Saya juga menghadapi kesalahan dalam tes multi-threaded. Jawaban oleh gna bekerja dalam kasus itu.

Arvidaa
sumber
20

Masalah yang sangat menarik. Dalam kasus saya, masalah ini terjadi ketika saya mencoba men-debug pengujian saya pada baris serupa ini:

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

Catatan penting adalah bahwa pengujian berjalan dengan benar tanpa debugging.

Bagaimanapun, ketika saya mengganti kode di atas dengan potongan kode di bawah ini maka saya dapat men-debug baris masalah tanpa masalah.

doReturn(fooBar).when(bar).getFoo();
Luke
sumber
Terima kasih, Sepertinya ada masalah yang sama dengan class data Kotlin sebagai kolom, dan solusi Anda telah menyelesaikannya!
Mohsen Mirhoseini
6

Bagi saya ini berarti saya menjalankan ini:

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

Jadi yang terjadi adalah mockito itu mendeteksi yang a.method2()dipanggil, dan memberi tahu saya bahwa saya tidak bisa kembali cdari a.method2()mana yang salah.

Perbaiki: gunakan doReturn(c).when(b).method1(a)sintaks gaya (bukan when(b.method1(a)).thenReturn(c);), yang akan membantu Anda menemukan bug tersembunyi dengan lebih ringkas dan cepat.

Atau dalam kasus khusus ini, setelah melakukan itu mulai menampilkan "NotAMockException" yang lebih akurat, dan saya mengubahnya untuk tidak lagi mencoba menetapkan nilai kembali dari objek non-tiruan.

rogerdpack
sumber
1
Kesalahan yang sama saya juga lakukan. Saya mengejek metode yang digunakan dalam method1, mengeksekusi dan mendapatkan pengecualian ini. Itu terselesaikan setelah saya menghapus kode itu.
Praveen. 883
5

Saya baru saja mengalami masalah ini. Masalahnya adalah metode yang saya coba tiru tidak memiliki pengubah akses. Menambahkan publik memecahkan masalah.

not_john
sumber
5

Saya mengalami kesalahan ini karena dalam pengujian saya, saya memiliki dua harapan, satu pada tiruan dan satu lagi pada tipe konkret

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();

Saya memperbaikinya dengan mengubah cls menjadi tiruan juga

Tzafrir
sumber
4

Dalam kasus saya, masalahnya disebabkan oleh mencoba mengejek metode statis dan lupa memanggil mockStatickelas. Juga saya lupa memasukkan kelas ke dalam@PrepareForTest()

ACV
sumber
2

Jika Anda menggunakan anotasi, mungkin Anda perlu menggunakan @Mock daripada @InjectMocks. Karena @InjectMocks berfungsi sebagai @Spy dan @Mock bersama-sama. Dan @Spy melacak metode yang baru saja dieksekusi dan Anda mungkin merasa bahwa data yang salah dikembalikan / diganti teksnya.

dillip pattnaik
sumber
2
" @InjectMocksbekerja sebagai @Spydan @Mockbersama - sama." <- menurutku itu salah. Dari mana Anda mendengar ini?
Etienne Miret
2

Dalam kasus saya, saya menggunakan keduanya @RunWith(MockitoJUnitRunner.class)dan MockitoAnnotations.initMocks(this). Ketika saya menghapusnya MockitoAnnotations.initMocks(this)bekerja dengan benar.

ihebiheb
sumber
1

Kesalahan:

org.mockito.exceptions.misusing.WrongTypeOfReturnValue:
String tidak bisa dikembalikan oleh size ()
size () harus dikembalikan int
***
Jika Anda tidak yakin mengapa Anda mendapatkan kesalahan di atas, baca terus.
Karena sifat sintaks di atas, masalah mungkin terjadi karena:
1. Pengecualian ini mungkin terjadi dalam
pengujian multi-thread yang salah tulis .
Silakan lihat FAQ Mockito tentang batasan pengujian konkurensi.
2. Spy di-stub menggunakan sintaks when (spy.foo ()). Then (). Lebih aman untuk menghentikan
mata-mata -
- dengan metode keluarga doReturn | Throw (). Selengkapnya di javadocs untuk
metode Mockito.spy ().

Kode Aktual:

@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

Solusi untuk memperbaiki masalah ini:

1 Hapus anotasi “@Mock”.

private ByteString mockByteString;

2 Tambahkan PowerMockito.mock

mockByteString = PowerMockito.mock(ByteString.class);
MUNISAMI DHANDAYUTHAPANI
sumber
1

Saya baru-baru ini mengalami masalah ini saat mengejek fungsi di kelas data Kotlin . Untuk beberapa alasan yang tidak diketahui, salah satu pengujian saya berakhir dalam keadaan beku. Ketika saya menjalankan tes lagi, beberapa tes saya yang sebelumnya lulus mulai gagal dengan WrongTypeOfReturnValuepengecualian.

Saya memastikan saya menggunakan org.mockito:mockito-inlineuntuk menghindari masalah dengan kelas terakhir (disebutkan oleh Arvidaa), tetapi masalahnya tetap ada. Apa yang memecahkannya bagi saya adalah menghentikan proses dan memulai ulang Android Studio . Ini menghentikan pengujian saya yang beku dan pengujian berikut berjalan tanpa masalah.

simonevertsson
sumber
1

@MockBean tidak ada pada kacang yang ingin Anda ejek

Budha
sumber
1

Saya mendapat masalah ini WrongTypeOfReturnValuekarena saya mengejek metode yang mengembalikan java.util.Optional;dengan com.google.common.base.Optional;karena formatter saya secara otomatis menambahkan impor yang hilang.

Mockito baru saja mengatakan kepada saya bahwa "metode sesuatu () harus mengembalikan Opsional" ...

RotS
sumber
1

Dalam kasus saya, kacang telah diinisialisasi menggunakan anotasi @Autowired alih-alih @MockBean

Jadi dengan cara ini, mengejek DAO dan Layanan membuat pengecualian tersebut

S. Dayneko
sumber
1
Ya, dalam kasus saya tes Layanan aplikasi Spring-Boot, MockBean harus digunakan saat mengejek Bean. Terima kasih!
Isaac Philip
1

Bagi saya masalahnya adalah tes multithread yang melakukan stubbing / verifikasi pada ejekan bersama. Itu mengarah pada WrongTypeOfReturnValuepengecualian melempar secara acak .

Ini bukan tes tertulis dengan benar menggunakan Mockito. Tiruan tidak boleh diakses dari beberapa utas.

Solusinya adalah membuat olok-olok lokal untuk setiap pengujian.

Damian
sumber
1

TL; DR Jika beberapa argumen dalam pengujian Anda null, pastikan untuk memalsukan panggilan parameter dengan isNull()alih - alih anyXXX().


Saya mendapat kesalahan ini saat memutakhirkan dari Spring boot 1.5.x ke 2.1.x. Spring boot dikirimkan dengan Mockito-nya sendiri, yang sekarang juga ditingkatkan ke 2.x (lihat misalnya Dependensi Spring boot 2.1.2 )

Mockito telah berubah perilaku untuk anyXXX()metode, di mana XXXadalah String, Long, dll Berikut adalah javadoc dari anyLong():

Sejak Mockito 2.1.0, hanya izinkan nilai Long, sehingga nulltidak lagi menjadi nilai yang valid. Karena pembungkus primitif dapat dinihilkan, API yang disarankan untuk mencocokkan null pembungkus adalah #isNull(). Kami merasa perubahan ini akan membuat pengujian memanfaatkan lebih aman dibandingkan dengan Mockito 1.x.

Saya sarankan Anda men-debug ke titik di mana tiruan Anda akan dipanggil dan diperiksa, apakah setidaknya ada satu argumen null. Dalam hal ini pastikan, bahwa Anda menyiapkan tiruan Anda dengan isNull()alih - alih misalnya anyLong().

Jadi ini:

when(MockedClass.method(anyString());

menjadi:

when(MockedClass.method(isNull());
Younes EO
sumber
-1

Ini kasus saya:

//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();

Lalu saya mendapatkan kesalahan ini:

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

Bisakah kamu menebak?

Masalahnya adalah Target.method1 () adalah metode statis. Mockito benar-benar memperingatkan saya tentang hal lain.

Surasin Tancharoen
sumber