khi tôi chạy thử nghiệm mockito xảy ra WrongTypeOfReturnValue Exception


96

Chi tiết lỗi:

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.

mã của tôi :

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

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

Như bạn thấy, tôi kêu gọi whentrên updateItemAttributes(mà không trở lại một boolean) không vào updateItemAttributesByJuId.

  1. Tại sao Mockito lại cố gắng trả lại booleantừ updateItemAttributesByJuId?
  2. Làm thế nào điều này có thể được khắc phục?

Câu trả lời:


198

Theo https://groups.google.com/forum/?fromgroups#!topic/mockito/9WUvkhZUy90 , bạn nên diễn đạt lại

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

đến

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

3
Đây là mẹo tuyệt vời. Tôi cũng gặp sự cố này khi thử nghiệm một số @Repositoryphương pháp Spring DAO với @Aspect . nếu tôi làm vậy when(someDao.someMethod()).thenReturn(List<xxx>), tôi có ngoại lệ WrongTypeOfReturnValue này. Thông qua gỡ lỗi, tôi có thể thấy rằng someMethodphương thức thực sự được gọi trong câu lệnh trên và kích hoạt Lời khuyên xung quanh và trả về a nullnhưng Mockito đang mong đợi a List<xxx>.
LeOn - Han Li

Làm việc cho tôi. Obrigado!
Nghệ sĩ saxophone

Câu trả lời xuất sắc. Đã lưu ngày của tôi.
user3198259

Cũng làm việc cho tôi! Cảm ơn! Mặc dù, tôi không hiểu đầy đủ lời giải thích trong liên kết được cung cấp.
georgeliatsos

40

Một lý do khác cho thông báo lỗi tương tự là cố gắng bắt chước một finalphương pháp. Người ta không nên cố gắng bắt chước các phương thức cuối cùng (xem Chế nhạo phương pháp cuối cùng ).

Tôi cũng đã đối mặt với lỗi trong một bài kiểm tra đa luồng. Câu trả lời của gna đã làm việc trong trường hợp đó.


20

Vấn đề rất được quan tâm. Trong trường hợp của tôi, sự cố này đã được gây ra khi tôi cố gắng gỡ lỗi các thử nghiệm của mình trên dòng tương tự này:

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

Lưu ý quan trọng là các bài kiểm tra đã chạy chính xác mà không cần gỡ lỗi.

Theo bất kỳ cách nào, khi tôi thay thế đoạn mã bên trên bằng đoạn mã bên dưới thì tôi có thể gỡ lỗi dòng sự cố mà không gặp sự cố.

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

Cảm ơn, Có vẻ như có cùng một vấn đề với các lớp dữ liệu Kotlin như các trường và giải pháp của bạn đã giải quyết được vấn đề đó!
Mohsen Mirhoseini

6

Đối với tôi, điều này có nghĩa là tôi đang chạy cái này:

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

Vì vậy, những gì đang xảy ra là mockito đã phát hiện ra a.method2()đang được gọi, và nói với tôi rằng tôi không thể quay lại ctừ a.method2()đó là sai.

Khắc phục: sử dụng doReturn(c).when(b).method1(a)cú pháp kiểu (thay vì when(b.method1(a)).thenReturn(c);), điều này sẽ giúp bạn phát hiện ra lỗi ẩn một cách ngắn gọn và nhanh chóng hơn.

Hoặc trong trường hợp cụ thể này, sau khi làm điều đó, nó bắt đầu hiển thị "NotAMockException" chính xác hơn và tôi đã thay đổi nó để không cố gắng đặt giá trị trả về từ một đối tượng không phải giả nữa.


1
Tôi cũng đã làm sai cùng một sai lầm. Tôi đã chế nhạo phương thức được sử dụng trong method1, được thực thi và có ngoại lệ này. Nó đã được giải quyết khi tôi xóa mã đó.
Praveen.883

5

Gần đây tôi đã có vấn đề này. Vấn đề là phương pháp tôi đang cố gắng mô phỏng không có công cụ sửa đổi truy cập. Thêm công khai đã giải quyết được vấn đề.


5

Tôi mắc phải lỗi này vì trong bài kiểm tra của tôi, tôi có hai kỳ vọng, một kỳ vọng vào mô hình và một kỳ vọng vào loại bê tông

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

Tôi đã sửa nó bằng cách thay đổi cls thành một mô hình


4

Trong trường hợp của tôi, vấn đề là do cố gắng bắt chước một phương thức tĩnh và quên gọi mockStaticlớp. Ngoài ra, tôi đã quên đưa lớp vào@PrepareForTest()


2

Nếu bạn đang sử dụng chú thích, có thể bạn cần sử dụng @Mock thay vì @InjectMocks. Vì @InjectMocks hoạt động như @Spy và @Mock cùng nhau. Và @Spy theo dõi các phương thức được thực thi gần đây và bạn có thể cảm thấy rằng dữ liệu không chính xác được trả về / phân chia.


2
" @InjectMockshoạt động như @Spy@Mockcùng nhau." <- điều đó có vẻ sai đối với tôi. Bạn đã nghe điều này từ đâu?
Etienne Miret

2

Trong trường hợp của tôi, tôi đã sử dụng cả hai @RunWith(MockitoJUnitRunner.class)MockitoAnnotations.initMocks(this). Khi tôi loại bỏ MockitoAnnotations.initMocks(this)nó hoạt động chính xác.


1

Lỗi:

org.mockito.exceptions.misusing.WrongTypeOfReturnValue:
Không thể trả về chuỗi theo size ()
size () nên trả về int
***
Nếu bạn không chắc chắn tại sao bạn gặp lỗi ở trên, hãy đọc tiếp.
Do bản chất của cú pháp, sự cố trên có thể xảy ra vì:
1. Ngoại lệ này có thể xảy ra trong các
bài kiểm tra đa luồng bị viết sai .
Vui lòng tham khảo Câu hỏi thường gặp về Mockito về các hạn chế của thử nghiệm đồng thời.
2. Một gián điệp bị bắt bằng cú pháp when (spy.foo ()). Then (). Sẽ an toàn hơn khi bắt giữ
gián điệp -
- với dòng phương thức doReturn | Throw (). Thêm trong javadocs cho
phương thức Mockito.spy ().

Mã thực tế:

@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

Giải pháp để khắc phục sự cố này:

1 Xóa chú thích “@Mock”.

private ByteString mockByteString;

Thêm lần 2 PowerMockito.mock

mockByteString = PowerMockito.mock(ByteString.class);

1

Gần đây tôi đã gặp sự cố này khi chế nhạo một hàm trong lớp dữ liệu Kotlin . Vì một số lý do không xác định, một trong những lần chạy thử nghiệm của tôi đã kết thúc ở trạng thái đóng băng. Khi tôi chạy lại các bài kiểm tra, một số bài kiểm tra của tôi đã vượt qua trước đó bắt đầu không thành công với WrongTypeOfReturnValuengoại lệ.

Tôi đảm bảo rằng tôi đang sử dụng org.mockito:mockito-inlineđể tránh các vấn đề với các lớp cuối cùng (được đề cập bởi Arvidaa), nhưng vấn đề vẫn còn. Điều giải quyết được vấn đề cho tôi là giết quá trình và khởi động lại Android Studio . Điều này đã chấm dứt quá trình chạy thử nghiệm bị đóng băng của tôi và các lần chạy thử nghiệm sau đã trôi qua mà không gặp sự cố.


1

Thiếu @MockBean trên hạt đậu mà bạn muốn chế nhạo


1

Tôi gặp sự cố này WrongTypeOfReturnValuevì tôi đã chế nhạo một phương thức trả về a java.util.Optional;vớicom.google.common.base.Optional; do trình định dạng của tôi tự động thêm các lần nhập bị thiếu.

Mockito chỉ nói với tôi rằng "method something () nên trả về Tùy chọn" ...


1

Trong trường hợp của tôi, bean đã được khởi tạo bằng cách sử dụng chú thích @Autowosystem thay vì @MockBean

Vì vậy, theo cách này, việc chế giễu các DAO và Dịch vụ sẽ ném ra một ngoại lệ như vậy


1
Có, trong trường hợp của tôi là kiểm tra Dịch vụ ứng dụng Spring-Boot, MockBean nên được sử dụng khi chế tạo Bean. cảm ơn!
Isaac Philip

1

Đối với tôi, vấn đề là các bài kiểm tra đa luồng đang thực hiện kiểm tra / xác minh trên một mô hình được chia sẻ. Nó dẫn đến WrongTypeOfReturnValuengoại lệ ném ngẫu nhiên .

Đây không phải là bài kiểm tra viết đúng cách bằng Mockito. Mocks không nên được truy cập từ nhiều chủ đề.

Giải pháp là tạo ra các mô phỏng cục bộ cho mỗi bài kiểm tra.


1

TL; DR Nếu một số đối số trong thử nghiệm của bạn là null, hãy đảm bảo mô phỏng lệnh gọi tham số isNull()thay vì anyXXX().


Tôi gặp lỗi này khi nâng cấp từ Spring boot 1.5.x lên 2.1.x. Spring boot đi kèm với Mockito của riêng nó, hiện cũng được nâng cấp lên 2.x (xem ví dụ: Phụ thuộc của Spring boot 2.1.2 )

Mockito đã thay đổi hành vi cho anyXXX()phương thức, đâu XXXString , Longvv Đây là javadoc của anyLong():

Vì Mockito 2.1.0, chỉ cho phép có giá trị Long, do đó nullkhông còn là giá trị hợp lệ Vì các trình bao bọc nguyên thủy không thể sử dụng được, API được đề xuất phải khớp null trình bao bọc sẽ là #isNull(). Chúng tôi cảm thấy sự thay đổi này sẽ giúp các thử nghiệm khai thác an toàn hơn nhiều so với Mockito 1.x.

Tôi khuyên bạn nên gỡ lỗi đến điểm mà mô hình của bạn sắp được gọi và kiểm tra, cho dù ít nhất một đối số hay không null. Trong trường hợp đó, hãy chắc chắn rằng bạn chuẩn bị mô hình của mình isNull()thay vì ví dụ anyLong().

Vì vậy, điều này:

when(MockedClass.method(anyString());

trở thành:

when(MockedClass.method(isNull());

-1

Đây là trường hợp của tôi:

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

Sau đó, tôi gặp lỗi này:

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

Bạn có thể đoán?

Vấn đề là Target.method1 () là một phương thức tĩnh. Mockito hoàn toàn cảnh báo tôi về một điều khác.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.