Làm cách nào để xác minh rằng một phương thức cụ thể không được gọi bằng Mockito?


625

Làm thế nào để xác minh rằng một phương thức không được gọi vào sự phụ thuộc của đối tượng?

Ví dụ:

public interface Dependency {
    void someMethod();
}

public class Foo {
    public bar(final Dependency d) {
        ...
    }
}

Với bài kiểm tra Foo:

public class FooTest {
    @Test
    public void dependencyIsNotCalled() {
        final Foo foo = new Foo(...);
        final Dependency dependency = mock(Dependency.class);
        foo.bar(dependency);
        **// verify here that someMethod was not called??**
    }
}

Câu trả lời:


1087

Thậm chí còn có ý nghĩa hơn:

import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;

// ...

verify(dependency, never()).someMethod();

Tài liệu của tính năng này có §4 "Xác minh chính xác số lần gọi / ít nhất là x / không bao giờ"neverjavadoc có ở đây .


144
Sử dụng neverlà cách tốt nhất và cụ thể nhất, nhưng nếu bạn cần kiểm tra toàn bộ một đối tượng giả, cũng xem xét verifyZeroInteractions(mockObject)hoặc verifyNoMoreInteractions(mockObject).
Jeff Bowman

Phải làm gì nếu someMethod là riêng tư ??
Sumit Kumar Saha

1
Sau đó, bạn không thể giả lập nó ở vị trí đầu tiên (với Mockito);) PowerMock cho phép điều đó nhưng nó phức tạp hơn để thiết lập. Hoặc nếu bạn có quyền sở hữu mã, bạn thư giãn khả năng hiển thị để đóng gói.
Brice

2
Kể từ 3.0.1 verifyZeroInteractionsđã không được chấp nhận. verifyNoInteractions là đề xuất thay thế. Phiên bản Mockito tại thời điểm nhận xét này là 3.3.3
VKB

108

sử dụng đối số thứ hai trên Mockito.verifyphương thức, như trong:

verify(dependency, Mockito.times(0)).someMethod()


11
công khai VerifyingMode không bao giờ () {lần trả về (0); }
gbero

3
never()không đáng kể dễ đọc hơn times(0). Nhưng sự tồn tại của neverkhông làm tăng tải nhận thức và làm cho hệ thống mockito khó hiểu hơn và nhớ cách sử dụng. Vì vậy, thực sự mockito không nên bao gồm nevertrong API của họ, nó không đáng giá cho chi phí tinh thần.
BT

Câu hỏi: biểu mẫu này có xác minh someMethodđược gọi 0 lần không, hoặc chỉ xác minh rằng someMethodkhông bao giờ được gọi với các đối số bằng 0?
BT

@BT - Tôi sẽ tưởng tượng nó xác minh someMethodvới các đối số bằng 0 được gọi là 0 lần - không được xác minh.
beluchin

18

Là một mô hình tổng quát hơn để làm theo, tôi có xu hướng sử dụng một @Afterkhối trong thử nghiệm:

@After
public void after() {
    verifyNoMoreInteractions(<your mock1>, <your mock2>...);
}

Sau đó, bài kiểm tra là miễn phí để xác minh những gì nên được gọi.

Ngoài ra, tôi thấy rằng tôi thường quên kiểm tra "không có tương tác", chỉ để sau đó phát hiện ra rằng mọi thứ đã được gọi là không nên có.

Vì vậy, tôi thấy mẫu này hữu ích để bắt tất cả các cuộc gọi bất ngờ chưa được xác minh cụ thể.


9
Tài liệu Mockito tuyên bố rằng không nên lạm dụng mẫu này - "Một lời cảnh báo: Một số người dùng đã thực hiện nhiều thao tác giả cổ điển, mong đợi-xác thực có xu hướng sử dụng verifyNoMoreInterilities () rất thường xuyên, ngay cả trong mọi phương thức kiểm tra. () không được khuyến nghị sử dụng trong mọi phương pháp thử nghiệm. verifyNoMoreInterilities () là một xác nhận hữu ích từ bộ công cụ kiểm tra tương tác. Chỉ sử dụng khi có liên quan. Lạm dụng nó dẫn đến các thử nghiệm quá hạn, ít bảo trì hơn. " Xem tại đây
Chadi

2
"Chỉ sử dụng khi có liên quan". Tôi cảm thấy rằng nó luôn luôn có liên quan. Tôi không thấy mô hình đó là lạm dụng: như tôi đã nói, nó phát hiện ra "những thứ được gọi là không nên có". Đối với tôi, đó là một phần xác minh quan trọng: nếu có thứ gì đó đang gọi một kho lưu trữ mà nó không nên sử dụng, tôi muốn biết về nó! Trừ khi có cách khác để xác minh mà không sử dụng verifyNoMoreInteractions? Các câu trả lời khác ở đây dựa vào người viết bài kiểm tra ghi nhớ rõ ràng để liệt kê ra các kiểm tra này: đó là quá dễ bị lỗi trong cuốn sách của tôi.
David Lavender

2
Tôi thấy bình luận này, nhưng cũng cảm thấy như lý do không thuyết phục. Tôi rất thích đọc thêm về lý do tại sao điều này không được khuyến khích.
tobinibot

2
@tobinibot Vì ý tưởng thử nghiệm đơn vị là để xác minh Hợp đồng. Hầu hết các hợp đồng thường không liên quan đến số lần một số phương thức khác được gọi, nhưng thay vào đó, việc truyền các tham số đã biết dẫn đến phản hồi đã biết. Bằng cách không sử dụng thêm các tương tác, về cơ bản, bạn đang xác minh dòng thực hiện theo từng dòng, điều này làm cho việc tái cấu trúc và triển khai trở nên tẻ nhạt. Đó không phải là điểm kiểm tra đơn vị.
Andrew T Finnell

8

Trước hết: bạn phải luôn nhập mockito tĩnh, theo cách này, mã sẽ dễ đọc hơn (và trực quan):

import static org.mockito.Mockito.*;

Thực tế, có nhiều cách để đạt được điều này, tuy nhiên, nó được cho là sạch hơn để sử dụng

verify(yourMock, times(0)).someMethod();

phương pháp trên tất cả các bài kiểm tra của bạn, khi trong các Bài kiểm tra khác, bạn sử dụng nó để xác nhận một số lần thực hiện nhất định như sau:

verify(yourMock, times(5)).someMethod();

Các lựa chọn thay thế là:

verify(yourMock, never()).someMethod();

Ngoài ra - khi bạn thực sự muốn đảm bảo một Đối tượng bị nhạo báng nào đó thực sự KHÔNG được gọi - bạn có thể sử dụng:

verifyZeroInteractions(yourMock)

7

Cả phương thức verifyNoMoreInteractions()verifyZeroInteractions()phương thức bên trong đều có cùng cách thực hiện như:

public static transient void verifyNoMoreInteractions(Object mocks[])
{
    MOCKITO_CORE.verifyNoMoreInteractions(mocks);
}

public static transient void verifyZeroInteractions(Object mocks[])
{
    MOCKITO_CORE.verifyNoMoreInteractions(mocks);
}

vì vậy chúng ta có thể sử dụng bất kỳ một trong số chúng trên đối tượng giả hoặc mảng đối tượng giả để kiểm tra xem không có phương thức nào được gọi bằng cách sử dụng các đối tượng giả.

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.