Mocking Void Methods กับ Mockito

1. ภาพรวม

ในบทช่วยสอนสั้น ๆ นี้เรามุ่งเน้นไปที่การเยาะเย้ยวิธีการโมฆะด้วย Mockito

เช่นเดียวกับบทความอื่น ๆ ที่มุ่งเน้นไปที่เฟรมเวิร์ก Mockito (เช่น Mockito Verify, Mockito When / Then และ Mockito's Mock Methods) คลาสMyList ที่แสดงด้านล่างจะถูกใช้เป็นผู้ทำงานร่วมกันในกรณีทดสอบ

เราจะเพิ่มวิธีการใหม่สำหรับบทช่วยสอนนี้:

public class MyList extends AbstractList { @Override public void add(int index, String element) { // no-op } }

2. การเยาะเย้ยและการตรวจสอบอย่างง่าย

เป็นโมฆะวิธีการที่สามารถใช้กับ Mockito ของdoNothing () , doThrow () , และ doAnswer ()วิธีการทำให้เยาะเย้ยและการตรวจสอบการใช้งานง่าย:

@Test public void whenAddCalledVerified() { MyList myList = mock(MyList.class); doNothing().when(myList).add(isA(Integer.class), isA(String.class)); myList.add(0, ""); verify(myList, times(1)).add(0, ""); }

อย่างไรก็ตามdoNothing ()เป็นพฤติกรรมเริ่มต้นของ Mockito สำหรับวิธีโมฆะ

whenAddCalledVerified ()เวอร์ชันนี้ทำสิ่งเดียวกับข้างบน:

@Test public void whenAddCalledVerified() { MyList myList = mock(MyList.class); myList(0, ""); verify(myList, times(1)).add(0, ""); } 

DoThrow ()สร้างข้อยกเว้น:

@Test(expected = Exception.class) public void givenNull_AddThrows() { MyList myList = mock(MyList.class); doThrow().when(myList).add(isA(Integer.class), isNull()); myList.add(0, null); } 

เราจะกล่าวถึงdoAnswer ()ด้านล่าง

3. การจับอาร์กิวเมนต์

เหตุผลหนึ่งในการแทนที่พฤติกรรมเริ่มต้นด้วยdoNothing ()คือการจับอาร์กิวเมนต์

ในตัวอย่างข้างต้นเราใช้ตรวจสอบ ()วิธีการในการตรวจสอบการขัดแย้งที่ผ่านมาเพิ่ม ()

อย่างไรก็ตามเราอาจต้องจับข้อโต้แย้งและทำอะไรบางอย่างเพิ่มเติมกับพวกเขา

ในกรณีเหล่านี้เราใช้doNothing ()เช่นเดียวกับที่เราทำข้างต้น แต่ด้วยArgumentCaptor :

@Test public void whenAddCalledValueCaptured() { MyList myList = mock(MyList.class); ArgumentCaptor valueCapture = ArgumentCaptor.forClass(String.class); doNothing().when(myList).add(any(Integer.class), valueCapture.capture()); myList.add(0, "captured"); assertEquals("captured", valueCapture.getValue()); } 

4. รับสายเพื่อเป็นโมฆะ

วิธีการหนึ่งอาจมีพฤติกรรมที่ซับซ้อนมากกว่าการเพิ่มหรือตั้งค่าเท่านั้น

สำหรับสถานการณ์เหล่านี้เราสามารถใช้คำตอบของ Mockito เพื่อเพิ่มพฤติกรรมที่เราต้องการ:

@Test public void whenAddCalledAnswered() { MyList myList = mock(MyList.class); doAnswer(invocation -> { Object arg0 = invocation.getArgument(0); Object arg1 = invocation.getArgument(1); assertEquals(3, arg0); assertEquals("answer me", arg1); return null; }).when(myList).add(any(Integer.class), any(String.class)); myList.add(3, "answer me"); } 

ตามที่อธิบายไว้ใน Mockito ของ Java 8 คุณลักษณะที่เราใช้แลมบ์ดามีคำตอบในการกำหนดพฤติกรรมที่กำหนดเองสำหรับเพิ่ม ()

5. การล้อเลียนบางส่วน

การล้อเลียนบางส่วนก็เป็นตัวเลือกเช่นกัน doCallRealMethod ()ของMockitoสามารถใช้สำหรับวิธีการโมฆะ :

@Test public void whenAddCalledRealMethodCalled() { MyList myList = mock(MyList.class); doCallRealMethod().when(myList).add(any(Integer.class), any(String.class)); myList.add(1, "real"); verify(myList, times(1)).add(1, "real"); } 

วิธีนี้เราสามารถเรียกวิธีการจริงและตรวจสอบได้ในเวลาเดียวกัน

6. บทสรุป

ในบทความสั้น ๆ นี้เราได้กล่าวถึงวิธีต่างๆ 4 วิธีในการเข้าใกล้วิธีการโมฆะเมื่อทดสอบกับ Mockito

เช่นเคยตัวอย่างมีอยู่ในโครงการ GitHub นี้