Challenge - 5 Problems
Fake Object Mastery
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate2:00remaining
Output of a JUnit test using a fake object
Consider the following JUnit test using a fake object to simulate a database. What will be the test result when running this code?
JUnit
public class UserServiceTest { static class FakeDatabase implements Database { public boolean saveUser(String user) { return true; // Always succeeds } } @org.junit.Test public void testSaveUser() { Database db = new FakeDatabase(); UserService service = new UserService(db); boolean result = service.registerUser("Alice"); org.junit.Assert.assertTrue(result); } } interface Database { boolean saveUser(String user); } class UserService { private final Database db; public UserService(Database db) { this.db = db; } public boolean registerUser(String user) { return db.saveUser(user); } }
Attempts:
2 left
💡 Hint
Look at what the fake database's saveUser method returns.
✗ Incorrect
The fake database's saveUser method always returns true, so the UserService's registerUser method returns true. The assertion assertTrue(result) passes, so the test passes.
❓ assertion
intermediate2:00remaining
Correct assertion for a fake object interaction
You have a fake object that records how many times a method was called. Which assertion correctly verifies that the method was called exactly 3 times?
JUnit
class FakeLogger { private int callCount = 0; public void log(String message) { callCount++; } public int getCallCount() { return callCount; } } @org.junit.Test public void testLogging() { FakeLogger logger = new FakeLogger(); logger.log("start"); logger.log("process"); logger.log("end"); // Which assertion is correct here? org.junit.Assert.assertEquals(3, logger.getCallCount()); }
Attempts:
2 left
💡 Hint
Check the exact number of times the log method was called.
✗ Incorrect
The log method was called exactly 3 times, so the call count is 3. The assertion assertEquals(3, logger.getCallCount()) correctly verifies this.
🔧 Debug
advanced2:00remaining
Identify the bug in this fake object usage
This JUnit test uses a fake object to simulate a payment gateway. The test always fails with a NullPointerException. What is the cause?
JUnit
class FakePaymentGateway implements PaymentGateway { public boolean processPayment(double amount) { return true; } } @org.junit.Test public void testPayment() { PaymentService service = new PaymentService(null); boolean success = service.pay(100.0); org.junit.Assert.assertTrue(success); } interface PaymentGateway { boolean processPayment(double amount); } class PaymentService { private PaymentGateway gateway; public PaymentService(PaymentGateway gateway) { this.gateway = gateway; } public boolean pay(double amount) { return gateway.processPayment(amount); } }
Attempts:
2 left
💡 Hint
Check what object is passed to PaymentService constructor.
✗ Incorrect
The PaymentService is constructed with null instead of the fake payment gateway, so calling gateway.processPayment causes a NullPointerException.
🧠 Conceptual
advanced1:30remaining
Purpose of fake objects in unit testing
Which statement best describes the main purpose of using fake objects in unit testing?
Attempts:
2 left
💡 Hint
Think about why we avoid using real dependencies in unit tests.
✗ Incorrect
Fake objects provide simplified, controllable versions of real dependencies to isolate the unit under test and avoid side effects.
❓ framework
expert2:30remaining
Using a fake object with JUnit and Mockito
Given the following JUnit test using Mockito, what will be the output of the assertion?
JUnit
import static org.mockito.Mockito.*; import org.junit.Test; import static org.junit.Assert.*; public class OrderServiceTest { @Test public void testOrderProcessing() { PaymentGateway fakeGateway = mock(PaymentGateway.class); when(fakeGateway.processPayment(anyDouble())).thenReturn(false); OrderService service = new OrderService(fakeGateway); boolean result = service.placeOrder(50.0); assertFalse(result); } } interface PaymentGateway { boolean processPayment(double amount); } class OrderService { private final PaymentGateway gateway; public OrderService(PaymentGateway gateway) { this.gateway = gateway; } public boolean placeOrder(double amount) { return gateway.processPayment(amount); } }
Attempts:
2 left
💡 Hint
Check what the mock is configured to return and what the assertion expects.
✗ Incorrect
The mock PaymentGateway is set to return false for any payment amount. The OrderService returns this value, so assertFalse(result) passes.