Mocking และ Stubbing ใน Unit Tests

การทดสอบใน Java เบื้องต้น

Maria Milusheva

Senior Software Engineer

แรงจูงใจ: Dependencies

ทบทวน dependency flow จากบทเรียนที่แล้ว: แอปแลกเปลี่ยนเงินตราขึ้นอยู่กับ bank server: กราฟ Mermaid แสดง dependency flow ของตัวอย่างธนาคาร

ไม่สามารถตรวจสอบการคำนวณได้ เพราะอัตราแลกเปลี่ยนเงินตรานั้นคาดเดาไม่ได้

การทดสอบใน Java เบื้องต้น

การจัดการ Dependency ในการทดสอบ

Mocking - การสร้างออบเจกต์หรือพฤติกรรมจำลองแทนของจริงที่ใช้งานยากในการทดสอบ ช่วยให้ทดสอบได้โดยไม่ต้องพึ่ง external dependencies


import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

ตัวอย่างการใช้ Mocking

การทดสอบใน Java เบื้องต้น

Mocking

  • Mock = เหมือนนักแสดงสมทบในละคร ทำหน้าที่แทนออบเจกต์จริงเฉพาะในขอบเขตของการทดสอบเท่านั้น

พิจารณาตัวอย่างจากบทเรียนที่แล้ว:

public double convertEuroTo(String currency, double amount) {
    double rate = this.bank.getRateEuroTo(currency);
    return amount * rate;
}

➡ สร้างออบเจกต์ที่คาดเดาได้สำหรับ EuropeanCentralBankServer เพื่อใช้ทดสอบ

การทดสอบใน Java เบื้องต้น

Mocking: การแลกเปลี่ยนเงินตรา

นี่คือวิธีทดสอบด้วย mock:

@Test
void convert_returnsExpectedValue() {
    EuropeanCentralBankServer bank = mock(EuropeanCentralBankServer.class);
    ExchangeApp exchangeApp = new ExchangeApp(bank);

// Need to program the mock so it works when(bank.getRateEuroTo("USD")).thenReturn(1.1);
// Calls getRateEuroTo from the mock object, obtaining our pre-programmed values double result = exchangeApp.convertEuroTo("USD", 1000); assertEquals(1100, result); // We can now assert on exact return values }
การทดสอบใน Java เบื้องต้น

ข้อผิดพลาดที่พบบ่อย

อย่าลืม program mock เสมอ:

@Test
void convert_returnsExpectedValue() {
    EuropeanCentralBankServer bank = mock(EuropeanCentralBankServer.class);
    ExchangeApp exchangeApp = new ExchangeApp(bank);

    // No mock programming - mock bank object doesn't know how to respond to getRateEuroTo
    double result = exchangeApp.convertEuroTo("USD", 1000);

    assertEquals(1100, result); // Will fail due to lack of mock setup
}
การทดสอบใน Java เบื้องต้น

Stubbing

การทดสอบล้มเหลวพร้อมข้อความ:

org.opentest4j.AssertionFailedError: 
Expected :1100.0
Actual   :0.0

การ program mock เรียกว่า stubbing

Stubbing - การกำหนดคำตอบสำเร็จรูปขั้นต่ำสำหรับการเรียกใช้งานในระหว่างการทดสอบ โดยปกติจะไม่ตอบสนองต่อสิ่งที่ไม่ได้ตั้งโปรแกรมไว้

การทดสอบใน Java เบื้องต้น

Exception กับ Mockito

Mockito ยังสามารถจำลองสถานการณ์ข้อผิดพลาดได้:

EuropeanCentralBankServer bank = mock(EuropeanCentralBankServer.class);
ExchangeApp exchangeApp = new ExchangeApp(bank);
// Instead of thenReturn() use thenThrow()
when(bank.getRateEuroTo("USD"))
        .thenThrow(new RuntimeException("Bank server unavailable."));

exchangeApp.convertEuroTo("USD", 1000); // getRateEuroTo will throw exception
การทดสอบใน Java เบื้องต้น

มาฝึกกันเถอะ!

การทดสอบใน Java เบื้องต้น

Preparing Video For Download...