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ó @RunWith
Annotation?
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ó @RunWith
Annotation?
Câu trả lời:
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.
Tạo mô phỏng theo cách thủ công với Mockito::mock
các tác phẩm bất kể phiên bản JUnit (hoặc khung thử nghiệm cho vấn đề đó).
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).
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ừ MockitoExtension
JavaDoc 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).
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 .
@Test
cần phải là công khai hay "gói riêng tư" là đủ tốt?
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
...
}
@ExtendWith(MockitoExtension.class)
tương đương @RunWith(MockitoJUnitRunner.class)
với JUnit4
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.Extension
cho 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 đó.
Và 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-jupiter
phụ 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-api
di 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-api
mà mockito-junit-jupiter
phụ thuộc vào.
mockito-junit-jupiter
kéo phiên bản thích hợp của junit-jupiter-api
?
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.
MockitoExtension
dường như không tồn tại trong mockito-core
phiên bản 3.0.0.
mockito-junit-jupiter
Bạn phải sử dụng @ExtendWith
chú 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ụ .