Cách sử dụng Mockito với JUnit5


103

Làm thế nào tôi có thể sử dụng tiêm với Mockito và JUnit 5?

Trong JUnit4, tôi chỉ có thể sử dụng @RunWith(MockitoJUnitRunner.class)Annotation. Trong JUnit5 không có @RunWithAnnotation?

Câu trả lời:


145

Có nhiều cách khác nhau để sử dụng Mockito - Tôi sẽ trình bày từng cách một.

Thủ công

Tạo mô phỏng theo cách thủ công với Mockito::mockcác tác phẩm bất kể phiên bản JUnit (hoặc khung thử nghiệm cho vấn đề đó).

Dựa trên chú thích

Sử dụng @Mock -annotation và lệnh gọi tương ứng MockitoAnnotations::initMocks để tạo mô-đun hoạt động bất kể phiên bản JUnit (hoặc khung thử nghiệm cho vấn đề đó nhưng Java 9 có thể can thiệp vào đây, tùy thuộc vào việc mã thử nghiệm có kết thúc trong một mô-đun hay không).

Phần mở rộng Mockito

JUnit 5 có một mô hình mở rộng mạnh mẽ và Mockito gần đây đã xuất bản một mô hình dưới ID nhóm / tạo tác org.mockito : mockito-junit-jupiter .

Bạn có thể áp dụng tiện ích mở rộng bằng cách thêm @ExtendWith(MockitoExtension.class)vào lớp thử nghiệm và chú thích các trường bị chế nhạo với @Mock. Từ MockitoExtensionJavaDoc của:

@ExtendWith(MockitoExtension.class)
public class ExampleTest {

    @Mock
    private List list;

    @Test
    public void shouldDoSomething() {
        list.add(100);
    }

}

Tài liệu MockitoExtension mô tả các cách khác để khởi tạo mocks, chẳng hạn như với phương thức chèn hàm tạo (nếu bạn chạy chậm các trường cuối cùng trong các lớp thử nghiệm).

Không có quy tắc, không có người chạy

Các quy tắc và trình chạy JUnit 4 không hoạt động trong JUnit 5, do đó, không thể sử dụng trình chạyMockitoRule và trình chạy Mockito .


6
Bây giờ có một Mockito Junit5 mở rộng chính thức đó là tương đương với MockitoJUnitRunner -> Mockito-junit-Jupiter
dan carter

Khi phần mở rộng chính thức cho Mockito được phát hành, đã viết một bài đăng trên blog với chi tiết hơn về cách cấu hình và sử dụng nó: solidsoft.wordpress.com/2018/03/27/…
Marcin Zajączkowski

Phương thức được chú thích với @Testcần phải là công khai hay "gói riêng tư" là đủ tốt?
Geek

Khi chạy các bài kiểm tra với Jupiter (thường được gọi là "JUnit 5"), các phương pháp kiểm tra chỉ cần hiển thị ở dạng gói.
Nicolai

57

Sử dụng Mockito's MockitoExtension. Phần mở rộng được chứa trong một cấu phần phần mềm mới mockito-junit-jupiter:

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-junit-jupiter</artifactId>
    <version>2.23.4</version>
    <scope>test</scope>
</dependency>

Nó cho phép bạn viết các bài kiểm tra như bạn sẽ làm với JUnit 4:

import org.mockito.junit.jupiter.MockitoExtension;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;

@ExtendWith(MockitoExtension.class)
class MyTest {

    @Mock
    private Foo foo;

    @InjectMocks
    private Bar bar; // constructor injection

    ...
}

6
@ExtendWith(MockitoExtension.class)tương đương @RunWith(MockitoJUnitRunner.class)với JUnit4
Sergey

9

Có nhiều cách khác nhau để làm nhưng cách sạch hơn và cũng tôn trọng triết lý JUnit 5 đang tạo ra org.junit.jupiter.api.extension.Extensioncho Mockito.

1) Tạo mocks theo cách thủ công sẽ làm mất đi lợi ích của việc kiểm tra Mockito bổ sung để đảm bảo bạn sử dụng đúng khung.

2) Gọi MockitoAnnotations.initMocks(this)trong mọi lớp thử nghiệm là mã tấm lò hơi mà chúng ta có thể tránh.
Và thiết lập này trong một lớp trừu tượng cũng không phải là một giải pháp tốt.
Nó ghép mọi lớp thử nghiệm với một lớp cơ sở.
Nếu sau đó bạn cần một lớp thử nghiệm cơ sở mới vì lý do chính đáng, bạn sẽ kết thúc với hệ thống phân cấp lớp 3 cấp. Hãy tránh điều đó.

3) Quy tắc kiểm tra là một đặc điểm riêng của JUnit 4.
Đừng nghĩ về điều đó.
tài liệu rõ ràng về điều đó:

Tuy nhiên, nếu bạn có ý định phát triển một phần mở rộng mới cho JUnit 5, vui lòng sử dụng mô hình mở rộng mới của JUnit Jupiter thay vì mô hình dựa trên quy tắc của JUnit 4.

4) Test Runner thực sự không phải là cách để mở rộng khuôn khổ JUnit 5.
JUnit 5 đã đơn giản hóa địa ngục của những người chạy trong JUnit 4 bằng cách cung cấp một mô hình mở rộng để viết các bài kiểm tra nhờ vào Phần mở rộng của JUnit 5.
Đừng nghĩ về điều đó.

Vì vậy, hãy ưu ái org.junit.jupiter.api.extension.Extensionđường đi.


CHỈNH SỬA: Trên thực tế, Mockito gói một phần mở rộng jupiter: mockito-junit-jupiter

Sau đó, rất đơn giản để sử dụng:

import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class)
public class FooTest {
     ...    
}

Đây là một bổ sung cho câu trả lời xuất sắc của Jonathan.

Bằng cách thêm cấu phần phần phụ thuộc vào mockito-junit-jupiter, việc sử dụng @ExtendWith(MockitoExtension.class)ngoại lệ tạo ra sau khi kiểm tra được thực hiện:

java.

Vấn đề là nó mockito-junit-jupiterphụ thuộc vào hai thư viện độc lập. Ví dụ cho mockito-junit-jupiter:2.19.0:

<dependency>
  <groupId>org.mockito</groupId>
  <artifactId>mockito-core</artifactId>
  <version>2.19.0</version>
  <scope>compile</scope>
</dependency>
<dependency>
  <groupId>org.junit.jupiter</groupId>
  <artifactId>junit-jupiter-api</artifactId>
  <version>5.1.0</version>
  <scope>runtime</scope>
</dependency>

Vấn đề là tôi đã sử dụng junit-jupiter-api:5.0.1.

Vì vậy, khi junit-jupiter-apidi chuyển vẫn thường xuyên về API, hãy chắc chắn bạn phụ thuộc vào cùng một phiên bản junit-jupiter-apimockito-junit-jupiterphụ thuộc vào.


tại sao không mockito-junit-jupiterkéo phiên bản thích hợp của junit-jupiter-api?
haelix

@haelix Vì chiến lược phiên bản được sử dụng cho sự phụ thuộc này dựa vào thư viện Mockito. Nhìn vào phiên bản ở đây mockito-junit-jupiter:2.19.0. Trong khi các phiên bản JUnit Jupiter bắt đầu bằng 5. mockito-junit-jupiter lẽ ra phải chỉ định trong mã định danh tạo tác của nó hai thứ (phiên bản Mockito và phiên bản JUnit Jupiter) để làm cho mọi thứ rõ ràng hơn. Ví dụ mockito-junit-jupiter-5.1:2.19.0để truyền đạt rằng thư viện được thiết kế cho JUnit Jupiter 5.1.
davidxxx

MockitoExtensiondường như không tồn tại trong mockito-corephiên bản 3.0.0.
Thunderforge

1
@Thunderforge Điều này được định nghĩa trongmockito-junit-jupiter
davidxxx

3

Bạn phải sử dụng @ExtendWithchú thích mới .

Thật không may, vẫn chưa có phần mở rộng nào được phát hành. Trên github, bạn có thể thấy triển khai beta cho tiện ích mở rộng. như một thử nghiệm demo ví dụ .

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.