Use a fake object to test user service without real database
Preconditions (2)
✅ Expected Result: UserService returns the name of the fake user without accessing a real database
import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; // User entity record User(int id, String name) {} // UserRepository interface interface UserRepository { User findUserById(int id); } // UserService uses UserRepository class UserService { private final UserRepository userRepository; public UserService(UserRepository userRepository) { this.userRepository = userRepository; } public String getUserName(int id) { User user = userRepository.findUserById(id); return user != null ? user.name() : null; } } // Fake UserRepository for testing class FakeUserRepository implements UserRepository { @Override public User findUserById(int id) { if (id == 1) { return new User(1, "FakeUser"); } return null; } } public class UserServiceTest { @Test void testGetUserNameReturnsFakeUserName() { UserRepository fakeRepo = new FakeUserRepository(); UserService userService = new UserService(fakeRepo); String userName = userService.getUserName(1); assertEquals("FakeUser", userName, "UserService should return the fake user's name"); } }
This test uses a fake object to replace the real UserRepository. The FakeUserRepository class implements the interface and returns a fixed user when asked for id 1. This avoids any real database calls.
The UserService is created with the fake repository. When getUserName(1) is called, it returns the name from the fake user. The test asserts this name matches the expected "FakeUser" string.
This approach keeps the test fast, isolated, and simple. It shows how to use fake objects to test logic without external dependencies.
Now add data-driven testing with 3 different user IDs and expected names
fake object in JUnit testing?DataService?implements keyword and must provide method implementations.implements and defines the method. public class FakeDataService extends DataService { public int getData() { return 42; } } incorrectly uses extends with an interface. public interface FakeDataService implements DataService { int getData(); } wrongly declares an interface implementing another interface with method body. public class FakeDataService { int getData() { return 42; } } lacks interface implementation.interface Calculator { int add(int a, int b); }
class FakeCalculator implements Calculator {
public int add(int a, int b) { return 10; }
}
@Test
void testAdd() {
Calculator calc = new FakeCalculator();
assertEquals(10, calc.add(3, 7));
}add method in FakeCalculator always returns 10 regardless of inputs.calc.add(3, 7) equals 10, which matches the fake's return value.interface UserRepository {
String findUserName(int id);
}
class FakeUserRepository implements UserRepository {
public String findUserName() {
return "TestUser";
}
}findUserName requires an int id parameter, but the fake method has no parameters.Pass the test and this pattern moves unknown