@RunWith (MockitoJUnitRunner.class) กับ MockitoAnnotations.initMocks (สิ่งนี้)


119

ในขณะที่เขียนการทดสอบ jUnit4 ใหม่ผมสงสัยว่าจะใช้@RunWith (MockitoJUnitRunner.class) หรือMockitoAnnotations.initMocks (นี้)

ฉันสร้างการทดสอบใหม่และวิซาร์ดสร้างการทดสอบโดยอัตโนมัติกับ Runner Javadocs สำหรับ MockitoJUnitRunner ระบุดังต่อไปนี้:

เข้ากันได้กับ JUnit 4.4 ขึ้นไปนักวิ่งรุ่นนี้จะเพิ่มพฤติกรรมต่อไปนี้:

เริ่มต้น mocks ที่มีคำอธิบายประกอบด้วย Mock ดังนั้นจึงไม่จำเป็นต้องใช้ MockitoAnnotations.initMocks (Object) อย่างชัดเจน Mocks เริ่มต้นก่อนวิธีการทดสอบแต่ละครั้ง ตรวจสอบการใช้งานกรอบหลังจากวิธีการทดสอบแต่ละวิธี

ยังไม่ชัดเจนสำหรับฉันว่าการใช้ Runner มีข้อได้เปรียบเหนือวิธีการinitMocks () ที่ฉันใช้ในอดีตหรือไม่

ความคิดเห็นหรือลิงก์ใด ๆ จะได้รับการชื่นชม!

คำตอบ:


148

MockitoJUnitRunnerinitMocks()จะช่วยให้คุณตรวจสอบอัตโนมัติของการใช้กรอบเช่นเดียวกับอัตโนมัติ

การตรวจสอบการใช้งานเฟรมเวิร์กโดยอัตโนมัตินั้นคุ้มค่าที่จะมี ช่วยให้คุณรายงานได้ดีขึ้นหากคุณทำผิดพลาดอย่างใดอย่างหนึ่งเหล่านี้

  • คุณเรียกคงwhenวิธีการ แต่ไม่เสร็จสมบูรณ์ stubbing กับการจับคู่thenReturn, หรือ thenThrow (ข้อผิดพลาด 1 ในโค้ดด้านล่าง)then

  • คุณเรียกverifyล้อเลียน แต่ลืมระบุวิธีการโทรที่คุณพยายามตรวจสอบ (ข้อผิดพลาด 2 ในโค้ดด้านล่าง)

  • คุณเรียกใช้whenวิธีหลังdoReturn, doThrowหรือ doAnswerและผ่านการเยาะเย้ย แต่ลืมที่จะให้วิธีการที่คุณกำลังพยายามที่จะต้นขั้ว (ข้อผิดพลาด 3 ในโค้ดด้านล่าง)

หากคุณไม่มีการตรวจสอบการใช้งานเฟรมเวิร์กข้อผิดพลาดเหล่านี้จะไม่ถูกรายงานจนกว่าจะมีการเรียกใช้เมธอด Mockito ต่อไปนี้ นี่อาจจะเป็น

  • ในวิธีการทดสอบเดียวกัน (เช่นข้อผิดพลาด 1 ด้านล่าง)
  • ในวิธีการทดสอบถัดไป (เช่นข้อผิดพลาด 2 ด้านล่าง)
  • ในชั้นเรียนการทดสอบถัดไป

หากเกิดขึ้นในการทดสอบครั้งล่าสุดที่คุณเรียกใช้ (เช่นข้อผิดพลาด 3 ด้านล่าง) จะไม่มีการรายงานเลย

ข้อผิดพลาดแต่ละประเภทอาจมีลักษณะดังนี้ สมมติว่า JUnit รันการทดสอบเหล่านี้ตามลำดับที่ระบุไว้ที่นี่

@Test
public void test1() {

    // ERROR 1
    // This compiles and runs, but it's an invalid use of the framework because 
    // Mockito is still waiting to find out what it should do when myMethod is called.
    // But Mockito can't report it yet, because the call to thenReturn might 
    // be yet to happen.
    when(myMock.method1());

    doSomeTestingStuff();

    // ERROR 1 is reported on the following line, even though it's not the line with
    // the error.
    verify(myMock).method2();

}

@Test
public void test2() {

    doSomeTestingStuff();

    // ERROR 2
    // This compiles and runs, but it's an invalid use of the framework because
    // Mockito doesn't know what method call to verify.  But Mockito can't report 
    // it yet, because the call to the method that's being verified might 
    // be yet to happen.
    verify(myMock);
}

@Test
public void test3() {

    // ERROR 2 is reported on the following line, even though it's not even in 
    // the same test as the error.
    doReturn("Hello").when(myMock).method1();


    // ERROR 3
    // This compiles and runs, but it's an invalid use of the framework because
    // Mockito doesn't know what method call is being stubbed.  But Mockito can't 
    // report it yet, because the call to the method that's being stubbed might 
    // be yet to happen.

    doReturn("World").when(myMock);

    doSomeTestingStuff(); 

    //  ERROR 3 is never reported, because there are no more Mockito calls. 
}

ตอนที่ฉันเขียนคำตอบนี้ครั้งแรกเมื่อกว่าห้าปีที่แล้วฉันเขียน

ดังนั้นฉันจะแนะนำให้ใช้MockitoJUnitRunnerทุกที่ที่เป็นไปได้ อย่างไรก็ตามตามที่ Tomasz Nurkiewicz ได้ระบุไว้อย่างถูกต้องคุณจะไม่สามารถใช้งานได้หากคุณต้องการนักวิ่ง JUnit คนอื่นเช่น Spring

คำแนะนำของฉันเปลี่ยนไปแล้ว ทีม Mockito ได้เพิ่มฟีเจอร์ใหม่ตั้งแต่ฉันเขียนคำตอบนี้เป็นครั้งแรก เป็นกฎ JUnit ซึ่งทำหน้าที่เดียวกับไฟล์MockitoJUnitRunner. แต่จะดีกว่าเพราะมันไม่ได้กีดกันการใช้งานของนักวิ่งคนอื่น ๆ

ประกอบด้วย

@Rule 
public MockitoRule rule = MockitoJUnit.rule();

ในชั้นเรียนทดสอบของคุณ สิ่งนี้เริ่มต้นการล้อเลียนและทำการตรวจสอบความถูกต้องของกรอบงานโดยอัตโนมัติ เช่นเดียวกับMockitoJUnitRunnerไม่ แต่ตอนนี้คุณสามารถใช้SpringJUnit4ClassRunnerหรือ JUnitRunner อื่น ๆ ได้เช่นกัน ตั้งแต่ Mockito 2.1.0 เป็นต้นไปมีตัวเลือกเพิ่มเติมที่ควบคุมประเภทของปัญหาที่ได้รับรายงาน


ฉันไม่สามารถพูดได้อย่างแน่นอนว่ามันเหมือนกัน ในกรณีทดสอบหนึ่งการตั้งค่า junit runner ล้มเหลวสำหรับฉันและไม่ได้ฉีด mocks ของฉันอย่างถูกต้องเว้นแต่ฉันจะทำการตั้งค่า initMocks
dtc

เราใช้ testng 6.8.8 + mockito 1.10.19 และเห็นได้ชัดว่าเราไม่สามารถใช้ MockitoJUnitRunner ได้ แต่กรอบการตรวจสอบยังคงใช้งานได้! และทำงานได้เหมือนกับ @David Wallace ใครช่วยอธิบายหน่อย เป็นเพราะเรายังมี @ Before * callbacks และ MockitoAnnotations.initMocks (this) หรือไม่?
yuranos

@ yuranos87 ฟังดูน่าจะเป็นคำถามใหม่นะ อย่าลืมใส่รหัสของคุณเมื่อคุณทำ - เป็นการถามแบบไม่มีจุดหมายว่า "ทำไมรหัสนี้ถึงทำ XYZ" ถ้าคุณไม่แสดงรหัส
Dawood ibn Kareem

1
การใช้โซลูชัน TestRunner มีประสิทธิภาพเหนือกว่ากฎ @
กฎ

1
@alexandroid @ExtendWithแนะนำที่ดีที่สุดของฉันคือให้คุณเขียนคำตอบของคุณเองโดยใช้ ไม่ใช่เรื่องที่ฉันรู้จริงๆ สิ่งที่ยอดเยี่ยมเกี่ยวกับ Stack Overflow คือในคำถามเช่นนี้คุณสามารถตอบคำถามที่ถูกต้องได้หลายคำตอบ
Dawood ibn Kareem

23

การใช้นักวิ่งช่วยให้คุณประหยัดการเข้ารหัสได้เล็กน้อย (ไม่จำเป็นต้องใช้@Beforeวิธีการ) บนมืออื่น ๆ SpringJUnit4ClassRunnerโดยใช้นักวิ่งบางครั้งก็เป็นไปไม่ได้เช่นเมื่อคุณกำลังใช้อย่างใดอย่างหนึ่งเช่น

แค่นั้นแหละ. มันเป็นเพียงเรื่องของความชอบ


2
นอกเหนือจากบรรทัด initMocks () วิธีการ @Before ยังคงจำเป็นสำหรับการตั้งค่าอื่น ๆ ใช่ไหม
OceanBlue

2
@OceanBlue: แน่นอนว่าหาก@BeforeวิธีการของคุณมีอะไรนอกเหนือinitMocks()จากที่คุณต้องรักษาไว้หลังจากย้ายไปที่นักวิ่ง
Tomasz Nurkiewicz

คำตอบของ David Wallace เกี่ยวกับการตรวจสอบความถูกต้องของกรอบตอบคำถามของฉันอย่างเต็มที่ดังนั้นฉันจึงยอมรับข้อนั้น แต่ +1 เพื่อชี้ให้เห็นว่านักวิ่งคนนี้ไม่สามารถใช้กับคนอื่นได้เช่น Spring ขอบคุณ!
OceanBlue

1
ฉันใช้ Spring Boot และฉันสามารถพูดได้ว่ามันSpringJUnit4ClassRunnerเริ่มต้น mocks ให้ฉันโดยอัตโนมัติ ฉันไม่รู้เกี่ยวกับฤดูใบไม้ผลิธรรมดา
gustavohenke
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.