- Mockito คืออะไร
- การตั้งค่า (Setting up) Mockito
- Mocking กับ Mockito
- คุณสมบัติหลัก (Core Features) ของ Mockito
- หัวข้อขั้นสูง (Advanced Topics)
ในโลกของการทำแอพและทำเว็บ การทดสอบเป็นองค์ประกอบที่สำคัญของวงจรชีวิตการทำแอพและทำเว็บ ช่วยให้มั่นใจได้ว่าโค้ดที่เขียนจะทำงานตามที่คาดไว้ในสถานการณ์ต่างๆ เมื่อพูดถึงการเขียนโปรแกรม Java Mockito โดดเด่นในฐานะหนึ่งในไลบรารีการทดสอบที่ได้รับความนิยมและใช้กันอย่างแพร่หลายสำหรับการพัฒนาชุดทดสอบที่มีคุณภาพสูงและแข็งแกร่ง
1. Mockito คืออะไร
Mockito เป็นกรอบจำลองสำหรับ Java ซึ่งทำให้กระบวนการสร้างวัตถุจำลองสำหรับการทดสอบหน่วยง่ายขึ้น วัตถุจำลองเป็นวัตถุจำลองที่เลียนแบบพฤติกรรมของวัตถุจริงในลักษณะควบคุม พวกเขาให้วิธีการแยกหน่วยของรหัสภายใต้การทดสอบและกำจัดการพึ่งพาที่อาจยากต่อการยกตัวอย่าง ตั้งค่า หรือทำลายในระหว่างการทดสอบ Mockito มี API ที่ทรงพลังและใช้งานง่ายสำหรับการสร้าง ตรวจสอบ และทำงานกับวัตถุจำลองเหล่านี้ในการทำแอพและทำเว็บ
2. การตั้งค่า (Setting up) Mockito
จากการเขียนนี้ รีลีสเสถียรล่าสุดของ Mockito คือ Mockito 3.7.7 ซึ่งต้องใช้ Java 6 หรือสูงกว่า วิธีที่ดีที่สุดในการเพิ่ม Mockito ในโครงการของคุณขึ้นอยู่กับเครื่องมือสร้างของคุณ
มาเวน (Maven)
หากคุณใช้ Maven ให้เพิ่มสิ่งต่อไปนี้ใน pom.xml
:
<dependencies>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.7.7</version>
<scope>test</scope>
</dependency>
</dependencies>
Gradle
หากคุณใช้ Gradle ให้เพิ่มสิ่งต่อไปนี้ใน build.gradle
:
dependencies {
testImplementation 'org.mockito:mockito-core:3.7.7'
}
3. Mocking กับ Mockito
เมื่อตั้งค่า Mockito แล้ว เราสามารถเริ่มใช้เพื่อสร้างวัตถุจำลองได้ ลองใช้ตัวอย่างง่ายๆ ของคลาส BookStore:
public class BookStore {
private Inventory inventory;
public BookStore(Inventory inventory) {
this.inventory = inventory;
}
public int getBookCount(String bookName) {
return inventory.countBooks(bookName);
}
}
ในตัวอย่างข้างต้น Inventory
เป็นการขึ้นต่อกันของ BookStore
มันเป็นการพึ่งพาที่ Mockito สามารถช่วยให้เราเยาะเย้ยได้ นี่คือตัวอย่างการทดสอบที่แสดงให้เห็นสิ่งนี้:
import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class BookStoreTest {
@Test
public void testGetBookCount() {
// Arrange
Inventory mockInventory = mock(Inventory.class);
when(mockInventory.countBooks("The Great Gatsby")).thenReturn(20);
BookStore bookStore = new BookStore(mockInventory);
// Act
int count = bookStore.getBookCount("The Great Gatsby");
// Assert
assertEquals(20, count);
}
}
4. คุณสมบัติหลัก (Core Features) ของ Mockito
การขัด (Stubbing)
การขัดคือกระบวนการกำหนดพฤติกรรมของวัตถุจำลอง เราเห็นตัวอย่างนี้เมื่อเราใช้ when().thenReturn()
เพื่อระบุค่าส่งคืนของเมธอด นอกจากนี้ยังเป็นไปได้ที่จะ stub วิธีการโยนข้อยกเว้น:
when(mockInventory.countBooks("The Great Gatsby")).thenThrow(new RuntimeException());
ตัวจับคู่อาร์กิวเมนต์ (Argument Matchers)
Mockito รองรับการใช้ตัวจับคู่อาร์กิวเมนต์ที่ยืดหยุ่น ตัวจับคู่เหล่านี้ให้การควบคุมเพิ่มเติมสำหรับพฤติกรรมจำลอง ทำให้คุณสามารถระบุพฤติกรรมตามคุณสมบัติของอาร์กิวเมนต์ ไม่ใช่แค่ความเท่าเทียมกัน ตัวอย่างเช่น:
when(mockInventory.countBooks(anyString())).thenReturn(20);
ตัวanyString()
จับคู่จะจับคู่กับสตริงใดๆ ซึ่งหมายความว่าเมธอด countBooks()
จะคืนค่า 20 ไม่ว่าจะส่งชื่อหนังสืออะไรก็ตาม
การตรวจสอบการโต้ตอบ (Verifying Interactions)
คุณสามารถตรวจสอบได้ว่าการโต้ตอบบางอย่างเกิดขึ้นระหว่างวัตถุของคุณภายใต้การทดสอบและการจำลองของคุณ ทำได้โดยใช้ verify()
วิธีการ ตัวอย่างเช่น:
verify(mockInventory, times(1)).countBooks("The Great Gatsby");
ข้อความนี้ยืนยันว่าเมธอด countBooks()
ของออบเจกต์ mockInventory
ถูกเรียกเพียงครั้งเดียวโดยมีอาร์กิวเมนต์ “The Great Gatsby”
การสอดแนม (Spies)
ในขณะที่การจำลองจะส่งกลับค่าเริ่มต้น (เช่น 0, เท็จ หรือ null) สำหรับการโทรที่ไม่ถูกระงับ ในทางกลับกัน การสอดแนมจะล้อมรอบวัตถุจริง และโดยค่าเริ่มต้น ผู้รับมอบสิทธิ์จะเรียกใช้เมธอดของวัตถุที่ห่อไว้ สิ่งนี้มีประโยชน์เมื่อคุณต้องการจำลองเฉพาะบางเมธอดของคลาสและคงลักษณะการทำงานเดิมของเมธอดอื่นๆ
List<String> list = new ArrayList<String>();
List<String> spyList = spy(list);
spyList.add("Test");
verify(spyList).add("Test");
assertEquals(1, spyList.size());
อาร์กิวเมนต์แคปเตอร์ (ArgumentCaptor)
ArgumentCaptor เป็นคุณสมบัติอันทรงพลังที่ให้คุณบันทึกข้อโต้แย้งที่ส่งผ่านไปยังเมธอดสำหรับการยืนยันเพิ่มเติม สิ่งนี้มีประโยชน์เมื่อคุณต้องการทำการยืนยันที่ซับซ้อนมากขึ้น หรือเมื่ออาร์กิวเมนต์ถูกสร้างขึ้นแบบไดนามิกและคุณต้องตรวจสอบค่าของมัน
ArgumentCaptor<String> argument = ArgumentCaptor.forClass(String.class);
verify(mockInventory).countBooks(argument.capture());
assertEquals("The Great Gatsby", argument.getValue());
5. หัวข้อขั้นสูง (Advanced Topics)
แม้ว่าบทความนี้จะให้ข้อมูลเบื้องต้นเกี่ยวกับ Mockito แต่ก็ควรสังเกตว่า Mockito เป็นเฟรมเวิร์กที่ทรงพลังและยืดหยุ่นมากซึ่งรองรับหัวข้อขั้นสูงที่หลากหลาย
Mocking void methods
Mockito จัดทำกลไกสำหรับการทำให้เป็นโมฆะซึ่งไม่ส่งคืนค่า แต่มักจะเปลี่ยนสถานะของระบบไม่ทางใดก็ทางหนึ่ง สิ่งนี้ทำได้โดยใช้ doAnswer()
วิธีการซึ่งต้องใช้อินเทอร์เฟซ Answer
Mocking final classes และ methods
ตามเนื้อผ้า Mockito ไม่อนุญาตให้ล้อเลียนคลาสและเมธอดสุดท้าย เนื่องจากการทำเช่นนั้นเกี่ยวข้องกับการสร้างคลาสย่อยและเมธอดที่เอาชนะ อย่างไรก็ตาม ในเวอร์ชัน 2.1.0 Mockito เสนอคุณลักษณะ ‘ฟักตัว’ ที่เปิดใช้งานพฤติกรรมนี้
Mockito และ JUnit5
Mockito เสนอส่วนขยายสำหรับ JUnit5 ที่เรียกว่า Mockito-JUnit-Jupiter ซึ่งช่วยให้ไวยากรณ์สะอาดขึ้นและรวมเข้ากับฟีเจอร์ JUnit5 ได้ดีขึ้น
Mockito เป็นเครื่องมือที่มีประสิทธิภาพและยืดหยุ่นสำหรับการเขียนการทดสอบหน่วยใน Java สนับสนุนวิธีการที่หลากหลายในการสร้าง ตรวจสอบ และทำงานกับวัตถุจำลอง และมีคุณสมบัติมากมายที่ช่วยให้คุณปรับแต่งแบบจำลองของคุณให้ตรงกับความต้องการในการทดสอบเฉพาะของคุณในการทำแอพและทำเว็บ
แม้ว่าคำแนะนำนี้จะครอบคลุมถึงพื้นฐาน แต่ความลึกและความซับซ้อนทั้งหมดของ Mockito สามารถชื่นชมได้โดยการทำงานกับมันในบริบทของโลกแห่งความเป็นจริงเท่านั้น หากคุณยังไม่ได้ดำเนินการ ให้ลอง Mockito ในโครงการถัดไปของคุณ และดูว่าจะช่วยปรับปรุงกระบวนการทดสอบของคุณได้อย่างไรในการทำแอพและทำเว็บ