Mockito ยืนยันการสั่งซื้อ / ลำดับของการเรียกเมธอด


205

มีวิธีการตรวจสอบว่ามีการmethodOneเรียกมาก่อนmethodTwoใน Mockito หรือไม่?

public class ServiceClassA {
    public void methodOne(){}
 }

public class ServiceClassB {
    public void methodTwo(){}
 }

public class TestClass {
    public void method(){
        ServiceClassA serviceA = new ServiceClassA();
        ServiceClassB serviceB = new ServiceClassB();
        serviceA.methodOne();
        serviceB.methodTwo();
    }
}

คำตอบ:


305

InOrder ช่วยให้คุณทำเช่นนั้น

ServiceClassA firstMock = mock(ServiceClassA.class);
ServiceClassB secondMock = mock(ServiceClassB.class);

Mockito.doNothing().when(firstMock).methodOne();   
Mockito.doNothing().when(secondMock).methodTwo();  

//create inOrder object passing any mocks that need to be verified in order
InOrder inOrder = inOrder(firstMock, secondMock);

//following will make sure that firstMock was called before secondMock
inOrder.verify(firstMock).methodOne();
inOrder.verify(secondMock).methodTwo();

5
สิ่งนี้ถูกต้องแม้ว่าการโทรไปยังไม่มีสิ่งใดจะไม่จำเป็นที่นี่ยกเว้นเป็นตัวยึดสำหรับการขัดอื่น ๆ Mockito จะยอมรับการเรียกใช้วิธีการโมฆะแบบเงียบ ๆ โดยค่าเริ่มต้น
Jeff Bowman

1
มันยอมรับพวกเขาในขณะที่วัตถุที่ไม่มีการอ้างอิงถ้าวัตถุมีการอ้างอิงจะมีข้อยกเว้น =)
Koitoer

14
พิจารณาinOrder.verifyNoMoreInteractions();หลังจากการตรวจสอบครั้งสุดท้ายในตัวอย่างนี้เพื่อตรวจสอบว่าไม่มีการโทรอื่น
DwB

1
เพียงเพื่อชี้แจง: มันปลอดภัยที่จะกำหนดในคำสั่งก่อนการตรวจสอบ - หลังจากเรียกใช้บางวิธี (ทดสอบ) บน mocks
3078523

มีผลเหมือนกันสำหรับinOrder(firstMock, secondMock)และinOrder(secondMock, firstMock)? บางทีคุณสามารถอัปเดตคำตอบเพื่อจดบันทึกเกี่ยวกับเรื่องนี้
kevinarpe

95

โปรดทราบว่าคุณยังสามารถใช้คลาสInOrderเพื่อตรวจสอบว่ามีการเรียกใช้เมธอดต่าง ๆ ตามลำดับในการจำลองครั้งเดียวไม่ใช่เพียงแค่ใน mocks สองรายการขึ้นไป

สมมติว่าฉันมีสองชั้นFooและBar:

public class Foo {
  public void first() {}
  public void second() {}
}

public class Bar {
  public void firstThenSecond(Foo foo) {
    foo.first();
    foo.second();
  }
}

แล้วฉันสามารถเพิ่มระดับทดสอบเพื่อทดสอบว่าBar's firstThenSecond()วิธีจริงเรียกfirst()แล้วsecond()และไม่ได้แล้วsecond() first()ดูรหัสทดสอบต่อไปนี้:

public class BarTest {
  @Test
  public void testFirstThenSecond() {
    Bar bar = new Bar();
    Foo mockFoo = Mockito.mock(Foo.class);
    bar.firstThenSecond(mockFoo);

    InOrder orderVerifier = Mockito.inOrder(mockFoo);
    // These lines will PASS
    orderVerifier.verify(mockFoo).first();
    orderVerifier.verify(mockFoo).second();

    // These lines will FAIL
    // orderVerifier.verify(mockFoo).second();
    // orderVerifier.verify(mockFoo).first();
  }
}

1
นี่ควรเป็นความเห็นต่อคำตอบที่ยอมรับไม่ใช่คำตอบใหม่ทั้งหมด
ACH

12
ฉันไม่เห็นด้วยกับความคิดเห็นของคุณ @ach ตัวอย่างรหัสช่วยดังนั้นคำตอบใหม่ที่เหมาะสม
Snekse

2
มีวิธีการตรวจสอบวิธีการเดียวกันเรียกว่าสองครั้ง แต่ตรวจสอบลำดับของพารามิเตอร์ที่ส่งผ่านหรือไม่ เช่นก่อนfind('foo')จากนั้นfind('bar')
Snekse

1
ดูเหมือนว่านี่อาจเป็นคำตอบของฉันstackoverflow.com/questions/36573399/…
Snekse

3
นี่เป็นตัวอย่างที่ดีกว่าคำตอบที่ยอมรับเพราะมันแสดงให้เห็นถึงการใช้งานทั่วไปมากกว่าdoNothing()
Archimedes Trajano

37

ใช่มีการอธิบายไว้ในเอกสารประกอบ คุณต้องใช้คลาสInOrder

ตัวอย่าง (สมมติว่าสอง mocks สร้างไว้แล้ว):

InOrder inOrder = inOrder(serviceAMock, serviceBMock);

inOrder.verify(serviceAMock).methodOne();
inOrder.verify(serviceBMock).methodTwo();

1

ด้วย BDD มัน

@Test
public void testOrderWithBDD() {


    // Given
    ServiceClassA firstMock = mock(ServiceClassA.class);
    ServiceClassB secondMock = mock(ServiceClassB.class);

    //create inOrder object passing any mocks that need to be verified in order
    InOrder inOrder = inOrder(firstMock, secondMock);

    willDoNothing().given(firstMock).methodOne();
    willDoNothing().given(secondMock).methodTwo();

    // When
    firstMock.methodOne();
    secondMock.methodTwo();

    // Then
    then(firstMock).should(inOrder).methodOne();
    then(secondMock).should(inOrder).methodTwo();


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