ฉันจะใช้การฉีดกับ Mockito และ JUnit 5 ได้อย่างไร?
ใน JUnit4 ฉันสามารถใช้@RunWith(MockitoJUnitRunner.class)
Annotation ได้ ใน JUnit5 ไม่มี@RunWith
Annotation?
ฉันจะใช้การฉีดกับ Mockito และ JUnit 5 ได้อย่างไร?
ใน JUnit4 ฉันสามารถใช้@RunWith(MockitoJUnitRunner.class)
Annotation ได้ ใน JUnit5 ไม่มี@RunWith
Annotation?
คำตอบ:
มีหลายวิธีในการใช้ Mockito - ฉันจะอธิบายทีละวิธี
การสร้าง mocks ด้วยตนเองMockito::mock
โดยไม่คำนึงถึงเวอร์ชัน JUnit (หรือกรอบการทดสอบสำหรับเรื่องนั้น)
ใช้@Mock -annotation และสายที่สอดคล้องกับMockitoAnnotations::initMocks
การสร้าง mocksทำงานโดยไม่คำนึงถึงรุ่น JUnit (หรือกรอบทดสอบสำหรับเรื่องที่ แต่ Java 9 อาจรบกวนที่นี่ขึ้นอยู่กับว่ารหัสการทดสอบจะสิ้นสุดลงในโมดูลหรือไม่)
JUnit 5 มีรูปแบบการขยายที่มีประสิทธิภาพและ Mockito ตีพิมพ์เมื่อเร็ว ๆ นี้หนึ่งในกลุ่ม / สิ่งประดิษฐ์รหัสorg.mockito : Mockito-junit-ดาวพฤหัสบดี
คุณสามารถใช้ส่วนขยายโดยการเพิ่ม@ExtendWith(MockitoExtension.class)
การเรียนการทดสอบและ annotating @Mock
เขตเยาะเย้ยด้วย จากMockitoExtension
JavaDoc:
@ExtendWith(MockitoExtension.class)
public class ExampleTest {
@Mock
private List list;
@Test
public void shouldDoSomething() {
list.add(100);
}
}
เอกสาร MockitoExtensionอธิบายถึงวิธีอื่น ๆ ในการสร้างอินสแตนซ์ mocks ตัวอย่างเช่นด้วย constructor injection (หากคุณ rpefer ฟิลด์สุดท้ายในคลาสทดสอบ)
กฎ JUnit 4 และนักวิ่งไม่ทำงานใน JUnit 5 ดังนั้นจึงไม่สามารถใช้ตัววิ่งMockitoRule
และMockitoได้
@Test
ต้องเป็นสาธารณะหรือ "แพ็กเกจส่วนตัว" ดีเพียงพอหรือไม่
ใช้ MockitoExtension
Mockito ส่วนขยายมีอยู่ในอาร์ติแฟกต์ใหม่mockito-junit-jupiter
:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>2.23.4</version>
<scope>test</scope>
</dependency>
ช่วยให้คุณสามารถเขียนแบบทดสอบได้ตามที่คุณทำกับ 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)
เทียบเท่า@RunWith(MockitoJUnitRunner.class)
กับ JUnit4
มีหลายวิธีในการทำ แต่วิธีที่สะอาดกว่าและยังเคารพในปรัชญา JUnit 5 คือการสร้าง org.junit.jupiter.api.extension.Extension
Mockito
1) การสร้างล้อเลียนด้วยตนเองทำให้สูญเสียประโยชน์ของการตรวจสอบ Mockito เพิ่มเติมเพื่อให้แน่ใจว่าคุณใช้กรอบงานอย่างถูกต้อง
2) การโทรMockitoAnnotations.initMocks(this)
ในทุกชั้นเรียนทดสอบคือรหัสแผ่นหม้อไอน้ำที่เราสามารถหลีกเลี่ยงได้
และการตั้งค่านี้ในคลาสนามธรรมก็ไม่ใช่ทางออกที่ดีเช่นกัน
มันจับคู่การทดสอบทุกคลาสกับคลาสพื้นฐาน
หากคุณต้องการคลาสทดสอบพื้นฐานใหม่ด้วยเหตุผลที่ดีคุณจะจบด้วยลำดับชั้นคลาส 3 ระดับ โปรดหลีกเลี่ยงสิ่งนั้น
3) กฎการทดสอบคือความจำเพาะของ JUnit 4
อย่าแม้แต่คิดว่า
และเอกสารมีความชัดเจนเกี่ยวกับเรื่องนี้:
อย่างไรก็ตามหากคุณตั้งใจจะพัฒนาส่วนขยายใหม่สำหรับ JUnit 5 โปรดใช้โมเดลส่วนขยายใหม่ของ JUnit Jupiter แทนรูปแบบตามกฎของ JUnit 4
4) Test Runner ไม่ใช่วิธีการขยายกรอบ JUnit 5
JUnit 5 ทำให้นรกของ Runners of JUnit 4 ง่ายขึ้นด้วยการจัดเตรียมโมเดลส่วนขยายสำหรับการทดสอบการเขียนด้วย JUnit 5 Extensions
อย่าแม้แต่คิดว่า
ดังนั้นโปรดใช้org.junit.jupiter.api.extension.Extension
วิธีนี้
แก้ไข: จริงๆแล้ว Mockito รวมส่วนขยายของดาวพฤหัสบดี: mockito-junit-jupiter
จากนั้นใช้งานง่ายมาก:
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
public class FooTest {
...
}
นี่คือคำตอบที่ยอดเยี่ยมของ Jonathan
โดยการเพิ่มการอ้างอิงmockito-junit-jupiter
สิ่งประดิษฐ์การใช้@ExtendWith(MockitoExtension.class)
ข้อยกเว้นต่อไปนี้ที่สร้างขึ้นเมื่อดำเนินการทดสอบ:
java.lang.NoSuchMethodError: org.junit.platform.commons.support.AnnotationSupport.findAnnotation (Ljava / util / Optional; Ljava / lang / Class;) Ljava / util / Optional;
ปัญหาคือ mockito-junit-jupiter
ขึ้นอยู่กับไลบรารีอิสระสองแห่ง ตัวอย่างเช่นสำหรับ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>
junit-jupiter-api:5.0.1
แต่ปัญหาก็คือผมใช้
ดังนั้นในขณะที่การjunit-jupiter-api
เคลื่อนไหวยังคงอยู่บ่อยครั้งในแง่ของ API ตรวจสอบให้แน่ใจว่าคุณใช้เวอร์ชันเดียวกันjunit-jupiter-api
นั้นmockito-junit-jupiter
ขึ้นอยู่กับ
mockito-junit-jupiter
ดึงเวอร์ชันที่เหมาะสมของjunit-jupiter-api
?
mockito-junit-jupiter:2.19.0
ดูรุ่นที่นี่ ในขณะที่ JUnit Jupiter เวอร์ชันเริ่มต้นด้วย5
. mockito-junit-jupiter ควรระบุไว้ในสิ่งประดิษฐ์ระบุสองสิ่ง (รุ่น Mockito และรุ่น JUnit Jupiter) เพื่อให้ชัดเจนขึ้น ตัวอย่างเช่นmockito-junit-jupiter-5.1:2.19.0
เพื่อสื่อว่าห้องสมุดถูกออกแบบมาสำหรับ JUnit Jupiter 5.1
MockitoExtension
ไม่ปรากฏในmockito-core
เวอร์ชัน 3.0.0
mockito-junit-jupiter
คุณต้องใช้@ExtendWith
คำอธิบายประกอบใหม่
น่าเสียดายที่ยังไม่มีการเปิดตัวส่วนขยาย บนgithubคุณจะเห็นการใช้งานเบต้าสำหรับส่วนขยาย เป็นตัวอย่างที่ทดสอบสาธิต