0
0
JUnittesting~5 mins

Fake objects in JUnit

Choose your learning style9 modes available
Introduction

Fake objects help test code by pretending to be real parts. They let us check how code works without using real systems.

When the real part is slow or hard to use during tests.
When the real part is not ready yet but you want to test your code.
When you want to control the behavior of a part to test different cases.
When the real part causes side effects like changing a database or sending emails.
When you want to isolate the code under test from other parts.
Syntax
JUnit
class FakeService implements ServiceInterface {
    @Override
    public String getData() {
        return "fake data";
    }
}

Fake objects are simple classes that implement the same interface as the real object.

They return fixed or controlled data to help test specific scenarios.

Examples
This fake database stores data in memory for testing instead of a real database.
JUnit
import java.util.HashMap;
import java.util.Map;

class FakeDatabase implements Database {
    private Map<String, String> data = new HashMap<>();

    @Override
    public String fetch(String key) {
        return data.getOrDefault(key, "default");
    }

    public void addData(String key, String value) {
        data.put(key, value);
    }
}
This fake email sender records emails instead of sending them, so tests can check what was "sent".
JUnit
import java.util.ArrayList;
import java.util.List;

class FakeEmailSender implements EmailSender {
    private List<String> sentEmails = new ArrayList<>();

    @Override
    public void send(String email) {
        sentEmails.add(email);
    }

    public List<String> getSentEmails() {
        return sentEmails;
    }
}
Sample Program

This test uses a fake service to check that the client gets the expected data. It does not use any real service.

JUnit
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
import java.util.*;

interface Service {
    String getData();
}

class FakeService implements Service {
    @Override
    public String getData() {
        return "fake data";
    }
}

class Client {
    private Service service;

    public Client(Service service) {
        this.service = service;
    }

    public String fetchData() {
        return service.getData();
    }
}

public class FakeObjectTest {
    @Test
    public void testFetchDataWithFake() {
        Service fakeService = new FakeService();
        Client client = new Client(fakeService);
        String result = client.fetchData();
        assertEquals("fake data", result);
    }
}
OutputSuccess
Important Notes

Fake objects are simpler than mocks or stubs and usually have working code.

Use fakes when you want a lightweight replacement that behaves like the real object.

Keep fake objects easy to understand and maintain.

Summary

Fake objects replace real parts with simple versions for testing.

They help test code without slow or unavailable dependencies.

Fakes implement the same interface and return controlled data.