การสอดส่องออบเจ็กต์จริง
ค้นพบวิธีใช้สายลับของ Mockito เพื่อทำม็อกออบเจ็กต์จริงเพียงบางส่วน โดยยังเรียกใช้เมธอดจริงและตรวจสอบการโต้ตอบได้
การสอดส่องออบเจ็กต์จริง เป็นบทเรียน Testing Mastery: JUnit, Mockito & Integration Tests ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Testing Mastery: JUnit, Mockito & Integration Tests และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Testing Mastery: JUnit, Mockito & Integration Tests มีบทเรียนทั้งหมด 4 บทเรียน
บางส่วนของบทเรียนนี้ยังไม่ได้รับการแปล และแสดงเป็นภาษาอังกฤษ
What are Mockito Spies?
In Mockito, you've learned to create mocks to fully control object behavior. But what if you only want to change a few methods while keeping the original behavior for others?
That's where spies come in! A spy wraps a real object, allowing you to:
- Call the object's actual methods by default.
- Override (stub) specific methods to return predefined values.
- Verify interactions with the real object.
Think of it as 'partial mocking' – using the real thing, but with a few tweaks.
Creating Your First Spy
Creating a spy is straightforward. Instead of Mockito.mock(), you use Mockito.spy() and pass in an instance of the real object you want to spy on.
Let's define a simple DataService class we'll use for our examples. This service will perform some operations.
import org.mockito.Mockito;
public class DataService {
public String fetchData(String id) {
return "Real data for " + id;
}
public int processData(String data) {
return data.length();
}
}
public class Main {
public static void main(String[] args) {
DataService realService = new DataService();
DataService spyService = Mockito.spy(realService);
System.out.println("Spy created successfully!");
}
}Spies Call Real Methods
The key characteristic of a spy is that, by default, it will call the actual methods of the object it's wrapping. This is different from a mock, which has no real implementation and returns default values.
Let's see our spyService call a real method:
import org.mockito.Mockito;
public class DataService {
public String fetchData(String id) {
System.out.println("--- Calling REAL fetchData for ID: " + id + " ---");
return "Real data for " + id;
}
public int processData(String data) {
return data.length();
}
}
public class Main {
public static void main(String[] args) {
DataService realService = new DataService();
DataService spyService = Mockito.spy(realService);
String result = spyService.fetchData("123");
System.out.println("Result from spy: " + result);
int processed = spyService.processData("Hello");
System.out.println("Processed data length: " + processed);
}
}Stubbing a Spy: Overriding Behavior
While spies call real methods by default, you can still stub them to return specific values or throw exceptions, just like with mocks. This lets you control parts of the object's behavior.
However, when stubbing a spy, it's often safer to use doReturn().when() syntax:
Mockito.when(spy.method()).thenReturn(value)might execute the real method first if it's called during thewhen()part.Mockito.doReturn(value).when(spy).method()avoids calling the real method during stubbing, which is crucial if the real method has side effects or throws exceptions.
Stubbing a Spy in Action
Let's stub our spyService's fetchData method to return a custom value for a specific ID, while other calls still go to the real method:
import org.mockito.Mockito;
public class DataService {
public String fetchData(String id) {
System.out.println("--- Calling REAL fetchData for ID: " + id + " ---");
return "Real data for " + id;
}
public int processData(String data) {
return data.length();
}
}
public class Main {
public static void main(String[] args) {
DataService realService = new DataService();
DataService spyService = Mockito.spy(realService);
// Stubbing the spy for a specific input
Mockito.doReturn("Mocked data for specific ID")
.when(spyService)
.fetchData("specialId");
// This call will return the mocked data
String result1 = spyService.fetchData("specialId");
System.out.println("Result for specialId: " + result1);
// This call will go to the real method
String result2 = spyService.fetchData("regularId");
System.out.println("Result for regularId: " + result2);
}
}Verifying Spy Interactions
Just like with mocks, you can use Mockito.verify() to ensure that certain methods were called on your spy. This is powerful for confirming that your code interacts with the real object as expected.
verify() works exactly the same for spies as it does for mocks. You can check:
- If a method was called.
- How many times it was called.
- With what arguments it was called.
Verifying Spy Calls Example
Let's verify that our fetchData method was called on the spy, even when it executed its real implementation:
import org.mockito.Mockito;
public class DataService {
public String fetchData(String id) {
System.out.println("--- Calling REAL fetchData for ID: " + id + " ---");
return "Real data for " + id;
}
public int processData(String data) {
return data.length();
}
}
public class Main {
public static void main(String[] args) {
DataService realService = new DataService();
DataService spyService = Mockito.spy(realService);
// Call a method on the spy (it will execute the real method)
spyService.fetchData("user1");
spyService.processData("data1");
spyService.fetchData("user2");
// Verify interactions
Mockito.verify(spyService).fetchData("user1");
Mockito.verify(spyService, Mockito.times(2)).fetchData(Mockito.anyString());
Mockito.verify(spyService).processData("data1");
System.out.println("Verification successful!");
}
}Spies vs. Mocks: The Key Difference
It's crucial to understand when to use a spy versus a traditional mock:
- Mocks: Create a completely fake object. All methods are 'empty' and return default values unless you explicitly stub them. Ideal for isolating the unit under test.
- Spies: Wrap a real object. All methods execute their actual implementation unless you explicitly stub them. Useful when you want to use most of the real object's behavior but control a few specific interactions.
Prefer mocks for true unit isolation. Use spies when dealing with complex objects where only a few methods need to be controlled, or for legacy code.
When to Use Spies
Spies are particularly useful in scenarios where:
- You're testing a class that interacts with a complex dependency, and you only need to override a small part of that dependency's behavior.
- You have a legacy class with many methods, and creating a full mock would be tedious, but you need to ensure some methods are called or return specific values.
- You want to test partial behavior of a real object without fully replacing it.
However, use them sparingly. Over-reliance on spies can lead to less isolated tests that are harder to maintain.
Quick Check: Spy Behavior
Consider a Logger class with a log(String message) method that prints to console. If you spy on a new Logger() object, what happens when you call spyLogger.log("Test") without any stubbing?
Recap: Spying on Real Objects
You've successfully learned about Mockito spies!
- Spies wrap real objects, allowing you to use their actual methods by default.
- You create them with
Mockito.spy(realObject). - You can stub specific methods using
doReturn().when(spy).method()to override their behavior. - You can verify interactions on spies using
Mockito.verify(), just like with mocks. - Use spies carefully, primarily when partial control over a real object is needed, rather than full isolation.
This flexibility helps you write more targeted tests for complex scenarios.
คำถามที่พบบ่อย
บทเรียน “การสอดส่องออบเจ็กต์จริง” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การสอดส่องออบเจ็กต์จริง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Testing Mastery: JUnit, Mockito & Integration Tests ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Testing Mastery: JUnit, Mockito & Integration Tests มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การสอดส่องออบเจ็กต์จริง”
ค้นพบวิธีใช้สายลับของ Mockito เพื่อทำม็อกออบเจ็กต์จริงเพียงบางส่วน โดยยังเรียกใช้เมธอดจริงและตรวจสอบการโต้ตอบได้ คุณปฏิบัติ Testing Mastery: JUnit, Mockito & Integration Tests ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Testing Mastery: JUnit, Mockito & Integration Tests หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Testing Mastery: JUnit, Mockito & Integration Tests บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “การสอดส่องออบเจ็กต์จริง” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Testing Mastery: JUnit, Mockito & Integration Tests นี้ได้ไหม
ได้ บทเรียน Testing Mastery: JUnit, Mockito & Integration Tests ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การกำหนดค่าที่ส่งกลับจากสตับ
- ตัวจับคู่อาร์กิวเมนต์ของ Mockito
- การสอดส่องออบเจ็กต์จริง
- การโยนข้อยกเว้นและการเรียกต่อเนื่อง