2013-04-09 11 views
22

Mockito dường như đang ném một số UnfinishedVerificationException khi tôi nghĩ rằng tôi đã làm mọi thứ chính xác. Đây là trường hợp thử nghiệm một phần của tôi:Mockito cung cấp cho UnfinishedVerificationException khi có vẻ như OK

HttpServletRequest req = mock(HttpServletRequest.class); 
when(req.getHeader("Authorization")).thenReturn("foo"); 

HttpServletResponse res = mock(HttpServletResponse.class); 

classUnderTest.doMethod(req, res); // Use the mock 

verify(res, never()); 
verify(req).setAttribute(anyString(), anyObject()); 

Và đây là lớp một phần và phương pháp:

class ClassUnderTest extends AnotherClass { 
    @Override 
    public String doMethod(ServletRequest req, ServletRequest res) { 
     // etc. 
     return "someString"; 
    } 
} 

Bỏ qua thực tế là bạn nên giao diện không bao giờ giả bạn không sở hữu, tại sao Mockito đem lại cho tôi những điều sau đây thông điệp?

org.mockito.exceptions.misusing.UnfinishedVerificationException: 
Missing method call for verify(mock) here: 
-> at (redacted) 

Example of correct verification: 
    verify(mock).doSomething() 

Also, this error might show up because you verify either of: final/private/equals()/hashCode() methods. 
Those methods *cannot* be stubbed/verified. 

at [test method name and class redacted] 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) 
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) 
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) 
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) 
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) 
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) 
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) 
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) 
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) 
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) 
at org.junit.runners.ParentRunner.run(ParentRunner.java:309) 
at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37) 
at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62) 
at org.junit.runner.JUnitCore.run(JUnitCore.java:160) 
... etc 
+0

Lớp 'classUnderTest' trông như thế nào? Chữ ký của phương thức là gì? Nó hoạt động tốt cho tôi với các lớp/phương thức không phải là công khai. –

+0

Tôi đã cập nhật câu hỏi với ClassUnderTest – Jonathan

+6

Dòng được đề cập đến trong thông báo (bạn đã biên tập lại) giống như dòng nơi ngoại lệ thực sự bị ném? Thông thường, nếu bạn đã xác minh chưa hoàn tất, Mockito sẽ không báo cáo nó cho đến thời điểm NEXT bạn sử dụng phương thức Mockito. Nó cũng có thể là vấn đề của bạn là trong phương pháp thử nghiệm ngay lập tức TRƯỚC KHI một trong những điều này. Đó là lý do tại sao Mockito báo cáo số dòng nơi lỗi xảy ra SEPARATELY từ chính bản thân dấu vết. –

Trả lời

38

Tôi vừa mới thấy chính bản thân mình và điều đó đã khiến tôi rất bối rối.

Như David đã đề cập ở trên, Mockito báo cáo lỗi trong tiếp theo Cuộc gọi phương thức Mockito có thể không có cùng phương pháp thử nghiệm. Trong khi thông báo ngoại lệ có chứa một tham chiếu đến vị trí thực tế, lỗi xảy ra, tôi thấy việc kiểm tra không chính xác không phản tác dụng đối với quá trình thử nghiệm. Và việc kiểm tra càng đơn giản thì càng có nhiều lỗi xảy ra trong bài kiểm tra tiếp theo!

Dưới đây là một sửa chữa dễ dàng mà sẽ đảm bảo các lỗi xuất hiện trong phương pháp kiểm tra chính xác:

@After 
public void validate() { 
    validateMockitoUsage(); 
} 

Từ các tài liệu Mockito here:

Mockito ném ngoại lệ nếu bạn lạm dụng nó để bạn biết nếu các bài kiểm tra của bạn được viết chính xác. Bí quyết là Mockito thực hiện xác thực lần sau khi bạn sử dụng khung (ví dụ: lần sau bạn xác minh, cuống, gọi mô hình, v.v ...). Nhưng mặc dù ngoại lệ có thể được ném trong bài kiểm tra tiếp theo, thông báo ngoại lệ chứa phần tử theo dõi điều hướng có vị trí của lỗi. Do đó bạn có thể nhấp và tìm địa điểm mà Mockito bị lạm dụng.

Đôi khi, bạn có thể muốn xác thực việc sử dụng khung công khai một cách rõ ràng. Ví dụ: một trong số người dùng muốn đặt validateMockitoUsage() trong phương thức @After của mình để mà anh ấy biết ngay khi anh ấy lạm dụng Mockito. Nếu không có nó, ông sẽ biết về nó không sớm hơn lần sau ông sử dụng khung . Một lợi ích nữa của việc có validateMockitoUsage() trong @After là jUnit runner sẽ luôn thất bại trong phương pháp thử với lỗi trong khi xác nhận 'tiếp theo' bình thường có thể không thành công phương pháp thử nghiệm tiếp theo . Nhưng mặc dù JUnit có thể báo cáo thử nghiệm tiếp theo là màu đỏ, đừng lo lắng về điều đó và chỉ cần nhấp vào phần tử theo dõi ngăn xếp có thể điều hướng trong thông báo ngoại lệ để xác định ngay vị trí bạn lạm dụng mockito.

+0

Xem lớp MockitoRule tại đây http://stackoverflow.com/questions/40793464/parameterized-testing-with-mockito-by-using-junit-rule – tkruse

19

này cũng có thể được gây ra nếu bạn cố gắng verify một phương pháp mà hy vọng đối số nguyên thủy với any():

Ví dụ, nếu phương pháp của chúng tôi có chữ ký này:

method(long l, String s); 

Và bạn cố gắng xác minh nó như thế này, nó sẽ thất bại với thông báo nói trên:

verify(service).method(any(), anyString()); 

Ch Ange nó để anyLong() và nó sẽ làm việc:

verify(service).method(anyLong(), anyString()); 
+0

Tại sao không vượt qua ** anyString() **? –

+1

@IgorGanapolsky Cảm ơn, đã đổi thành anyString() –

+0

bạn là người hùng cá nhân của tôi. cảm ơn bạn rất nhiều. – Robert

0

tôi đã ngoại lệ tương tự với lớp MyRepository

org.mockito.exceptions.misusing.UnfinishedVerificationException: Thiếu phương pháp kêu gọi xác minh (giả) ở đây: -> ở MyRepository $$ $$ FastClassBySpringCGLIB de8d8358.invoke()

Ví dụ về đúng xác minh:

verify(mock).doSomething() 

Sự cố đã được giải quyết khi tôi tạo giao diện cho MyRepository và giao diện giả, nhưng không thực hiện. Có vẻ như mùa xuân tạo ra một số proxy CGLIB và nó dẫn đến ngoại lệ UnfinishedVerificationException.

1

Đối với tôi vấn đề hóa ra là một tuyên bố đậu bị thiếu trong ngữ cảnh thử nghiệm xml. Đó là cho một lớp khía cạnh tùy chỉnh được sử dụng bởi một lớp khác, một cá thể trong đó là một tham số cho hàm tạo của lớp là tham số để không thực hiện cuộc gọi verify(). Vì vậy, tôi đã thêm tuyên bố bean vào ngữ cảnh xml và nó hoạt động tốt sau đó.