Sobes.tech
Middle

What is the difference between stub and mock?

sobes.tech AI

Answer from AI

Stub is a simple placeholder object that returns predefined values in response to method calls, without containing complex logic. It is used to isolate the tested code from its dependencies and provide controlled responses.

Mock is a placeholder object with expectations regarding how and how many times its methods will be called. It is used to verify interactions between objects, not just return values. A mock object will throw an exception if method calls do not meet the set expectations.

Main differences:

  • Purpose: Stub focuses on providing data for testing, mock on behavior and interaction verification.
  • Verification: Stub does not check how its methods are called. Mock actively verifies method calls.
  • Expectation setting: Stub usually does not require expectation setting. Mock requires setting expectations before the test.
// Example of using Stub (without a specific library)
// Suppose we have a dependency service
interface DependentService {
    String getData();
}

// Stub implementation
class DependentServiceStub implements DependentService {
    @Override
    public String getData() {
        return "stub data"; // Returns a hardcoded value
    }
}

// Class under test that uses the dependency
class MyService {
    private DependentService dependentService;

    public MyService(DependentService dependentService) {
        this.dependentService = dependentService;
    }

    public String processData() {
        return "Processed: " + dependentService.getData();
    }
}

// In the test, we create MyService with DependentServiceStub
// and check that processData returns the expected result
// String result = new MyService(new DependentServiceStub()).processData();
// Assertions.assertEquals("Processed: stub data", result); // Stub simply provides data
// Example of using Mock (with Mockito)
// Suppose we are testing another class that interacts with DependentService
class AnotherService {
    private DependentService dependentService;

    public AnotherService(DependentService dependentService) {
        this.dependentService = dependentService;
    }

    public void doSomething() {
        dependentService.getData();
        // Possibly other method calls on dependentService
    }
}

// In the test, we will use a mock object.
// We will verify if getData() was called.
// DependentService mockDependentService = Mockito.mock(DependentService.class);
// AnotherService anotherService = new AnotherService(mockDependentService);

// Execute the method under test
// anotherService.doSomething();

// Verify that getData() was called once
// Mockito.verify(mockDependentService, Mockito.times(1)).getData(); // Mock verifies interaction