วิธีการตรวจสอบว่าวิธีการเฉพาะไม่ได้เรียกว่าใช้ Mockito?


625

วิธีการตรวจสอบว่าวิธีการไม่ได้เรียกว่าการพึ่งพาของวัตถุ?

ตัวอย่างเช่น:

public interface Dependency {
    void someMethod();
}

public class Foo {
    public bar(final Dependency d) {
        ...
    }
}

ด้วยการทดสอบฟู:

public class FooTest {
    @Test
    public void dependencyIsNotCalled() {
        final Foo foo = new Foo(...);
        final Dependency dependency = mock(Dependency.class);
        foo.bar(dependency);
        **// verify here that someMethod was not called??**
    }
}

คำตอบ:


1087

มีความหมายมากยิ่งขึ้น:

import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;

// ...

verify(dependency, never()).someMethod();

เอกสารของคุณลักษณะนี้จะมี§4 "การตรวจสอบจำนวนที่แน่นอนของสวด / อย่างน้อย x / ไม่เคย"และneverJavadoc เป็นที่นี่


144
ใช้neverเป็นที่ดีที่สุดและมากที่สุดวิธีการเฉพาะ แต่ถ้าคุณจำเป็นต้องตรวจสอบวัตถุจำลองทั้งยังพิจารณาหรือverifyZeroInteractions(mockObject) verifyNoMoreInteractions(mockObject)
Jeff Bowman

จะทำอย่างไรถ้ามีวิธีส่วนตัว?
Sumit Kumar Saha

1
จากนั้นคุณไม่สามารถเยาะเย้ยมันในสถานที่แรก (ด้วย Mockito);) PowerMock อนุญาตให้ทำเช่นนั้น แต่มันมีความซับซ้อนมากขึ้นในการตั้งค่า หรือถ้าคุณมีกรรมสิทธิ์ของรหัสคุณผ่อนคลายการเปิดเผยแพคเกจ
Brice

2
ตั้งแต่ 3.0.1 verifyZeroInteractionsเลิกใช้แล้ว verifyNoInteractions เป็นทางเลือกที่แนะนำ รุ่น Mockito ในขณะที่ความคิดเห็นนี้คือ 3.3.3
VKB

108

ใช้อาร์กิวเมนต์ที่สองในMockito.verifyวิธีการเช่นเดียวกับใน:

verify(dependency, Mockito.times(0)).someMethod()


11
VerificationMode สาธารณะคงที่ไม่ () {กลับมาครั้งที่ (0); }
gbero

3
never()times(0)ไม่ได้เป็นอย่างมีนัยสำคัญที่สามารถอ่านได้มากกว่า แต่การดำรงอยู่ของneverมันจะเพิ่มภาระการรับรู้และทำให้ระบบ mockito ยากต่อการเข้าใจและจดจำวิธีการใช้ ดังนั้น mockito จริง ๆ ไม่ควรรวมอยู่neverใน API ของพวกเขามันไม่คุ้มกับค่าใช้จ่ายทางจิต
BT

คำถาม: แบบฟอร์มนี้ตรวจสอบความถูกต้องที่someMethodเรียกว่า 0 ครั้งหรือไม่เพียง แต่ตรวจสอบว่าsomeMethodไม่เคยถูกเรียกว่ามีข้อโต้แย้งเป็นศูนย์หรือไม่
BT

@ BT - ฉันคิดว่ามันจะตรวจสอบsomeMethodกับข้อโต้แย้งเป็นศูนย์ที่เรียกว่าศูนย์ครั้ง - ไม่ตรวจสอบ
beluchin

18

ตามรูปแบบทั่วไปที่จะต้องติดตามฉันมักจะใช้@Afterบล็อกในการทดสอบ:

@After
public void after() {
    verifyNoMoreInteractions(<your mock1>, <your mock2>...);
}

จากนั้นการทดสอบมีอิสระที่จะตรวจสอบเฉพาะสิ่งที่ควรเรียก

นอกจากนี้ฉันพบว่าฉันมักจะลืมตรวจสอบ "ไม่มีการโต้ตอบ" เพียงเพื่อค้นพบในภายหลังว่าสิ่งที่ถูกเรียกว่าไม่ควรได้รับ

ดังนั้นฉันจึงพบว่ารูปแบบนี้มีประโยชน์สำหรับการจับสายที่ไม่คาดคิดทั้งหมดที่ไม่ได้รับการยืนยันโดยเฉพาะ


9
เอกสาร Mockito ระบุว่ารูปแบบนี้ไม่ควรถูกนำไปใช้ - "คำเตือน: ผู้ใช้บางคนที่ใช้การเยาะเย้ยแบบคลาสสิกที่คาดว่าจะเรียกใช้ตรวจสอบมักจะใช้ () ไม่แนะนำให้ใช้ในทุกวิธีการทดสอบ VerifyNoMoreInteractions () เป็นคำยืนยันที่มีประโยชน์จากชุดเครื่องมือทดสอบการโต้ตอบใช้งานได้เฉพาะเมื่อมีความเกี่ยวข้องเท่านั้นการใช้แบบผิดวิธีจะนำไปสู่การทดสอบที่เกินขนาดและบำรุงรักษาน้อยกว่า " ดูที่นี่
Chadi

2
"ใช้เฉพาะเมื่อมีความเกี่ยวข้อง" ฉันรู้สึกว่ามันมีความเกี่ยวข้องเสมอ ฉันไม่เห็นรูปแบบนั้นเป็นการละเมิด: อย่างที่ฉันพูดไปแล้วพบว่า "สิ่งต่าง ๆ ถูกเรียกว่าไม่ควรเป็น" สำหรับฉันนั่นเป็นส่วนสำคัญในการตรวจสอบ: หากมีสิ่งที่เรียกว่าที่เก็บซึ่งไม่ควรใช้ฉันต้องการรู้เกี่ยวกับมัน! หากไม่มีวิธีอื่นในการตรวจสอบว่าไม่มีการใช้งานverifyNoMoreInteractionsหรือไม่ คำตอบอื่น ๆ ที่นี่ขึ้นอยู่กับนักเขียนทดสอบที่จำได้ว่าจะออกรายการตรวจสอบเหล่านี้อย่างชัดเจน: นั่นเป็นข้อผิดพลาดมากเกินไปในหนังสือของฉัน
David Lavender

2
ฉันเห็นความคิดเห็นนี้ แต่ก็รู้สึกเหมือนเหตุผลไม่น่าสนใจ ฉันชอบที่จะอ่านเพิ่มเติมเกี่ยวกับสาเหตุที่ไม่แนะนำ
tobinibot

2
@tobinibot เนื่องจากแนวคิดของการทดสอบหน่วยคือการตรวจสอบสัญญา โดยทั่วไปสัญญาส่วนใหญ่จะไม่เกี่ยวข้องกับวิธีการที่เรียกใช้วิธีอื่นหลายครั้ง แต่การส่งผ่านพารามิเตอร์ที่รู้จักส่งผลให้เกิดการตอบสนองที่ทราบ โดยไม่ต้องใช้การโต้ตอบอีกต่อไปคุณจะตรวจสอบความถูกต้องของการติดตั้งใช้งานทีละบรรทัดซึ่งทำให้การปรับโครงสร้างและการนำไปใช้งานน่าเบื่อ ซึ่งไม่ใช่จุดของการทดสอบหน่วย
Andrew T Finnell

8

ก่อนอื่น: คุณควรนำเข้า mockito คงที่วิธีนี้รหัสจะสามารถอ่านได้มากขึ้น (และใช้งานง่าย):

import static org.mockito.Mockito.*;

จริงๆแล้วมีหลายวิธีในการบรรลุเป้าหมายนี้ แต่มันก็สะอาดกว่าที่จะใช้

verify(yourMock, times(0)).someMethod();

วิธีการทั้งหมดของการทดสอบของคุณเมื่อทดสอบอื่น ๆ ที่คุณใช้เพื่อยืนยันจำนวนการประหารชีวิตเช่นนี้:

verify(yourMock, times(5)).someMethod();

ทางเลือกคือ:

verify(yourMock, never()).someMethod();

อีกทางเลือกหนึ่ง - เมื่อคุณต้องการให้แน่ใจว่าวัตถุที่ถูกเยาะเย้ยไม่ได้ถูกเรียกใช้จริงๆ - คุณสามารถใช้:

verifyZeroInteractions(yourMock)

7

ทั้งสองverifyNoMoreInteractions()และverifyZeroInteractions()วิธีการภายในมีการใช้งานเช่นเดียวกับ

public static transient void verifyNoMoreInteractions(Object mocks[])
{
    MOCKITO_CORE.verifyNoMoreInteractions(mocks);
}

public static transient void verifyZeroInteractions(Object mocks[])
{
    MOCKITO_CORE.verifyNoMoreInteractions(mocks);
}

เพื่อให้เราสามารถใช้หนึ่งในนั้นในวัตถุจำลองหรืออาร์เรย์ของวัตถุจำลองเพื่อตรวจสอบว่าไม่มีวิธีการใดที่เรียกว่าใช้วัตถุจำลอง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.