ฉันจะใช้การฉีดกับ Mockito และ JUnit 5 ได้อย่างไร?
ใน JUnit4 ฉันสามารถใช้@RunWith(MockitoJUnitRunner.class)Annotation ได้ ใน JUnit5 ไม่มี@RunWithAnnotation?
ฉันจะใช้การฉีดกับ Mockito และ JUnit 5 ได้อย่างไร?
ใน JUnit4 ฉันสามารถใช้@RunWith(MockitoJUnitRunner.class)Annotation ได้ ใน JUnit5 ไม่มี@RunWithAnnotation?
คำตอบ:
มีหลายวิธีในการใช้ 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เขตเยาะเย้ยด้วย จากMockitoExtensionJavaDoc:
@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ต้องเป็นสาธารณะหรือ "แพ็กเกจส่วนตัว" ดีเพียงพอหรือไม่
                    ใช้ MockitoExtensionMockito ส่วนขยายมีอยู่ในอาร์ติแฟกต์ใหม่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.ExtensionMockito    
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คุณจะเห็นการใช้งานเบต้าสำหรับส่วนขยาย เป็นตัวอย่างที่ทดสอบสาธิต