Software Testing
Mock vs Stub
Programming Concepts
Unit Testing
Test Doubles

What's the difference between a mock & stub?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

In software development, particularly within the realms of testing and behavior verification, two critical concepts are often talked about: mocks and stubs. These tools are integral to the process of unit testing, where individual components of the software are tested in isolation. Understanding the distinction between mocks and stubs is crucial for applying the right testing strategy and ensuring the quality of the application.

Definitions and Purposes

Stubs and mocks are both types of test doubles, terms originally coined by Gerard Meszaros in his book "XUnit Test Patterns". Test doubles are used in tests to replace components that a unit of code depends on. The primary purpose of using these is to isolate the behavior of the system under test, ensuring that tests run quickly and do not have external dependencies like databases or network services.

Stub: A stub is a minimal implementation of an interface that returns hardcoded data while simulating certain behaviors of components the unit under test interacts with. Its main purpose is to support the test by providing the necessary responses from its interfaces, thus isolating the unit from external dependencies and behaviors.

Mock: A mock object is designed to test interactions between components. It not only simulates the behavior of complex real objects in a controlled way but also allows verification of how it’s used in the unit under test. It checks if the interactions are happening as expected, such as method calls and parameters passed.

Technical Comparison

In a more technical light, while a stub might always return the same output, a mock can be used to verify particular properties of the interaction. This could include the number of method calls, the order of method calls, or the specific data received as parameters.

Examples

  1. Using a Stub
java
1    public class PaymentServiceStub implements PaymentService {
2        @Override
3        public boolean processPayment(double amount) {
4            // Always return true for simplicity 
5            return true;
6        }
7    }

In this Java example, PaymentServiceStub is a stub that simulates a payment service. It is particularly useful when the actual PaymentService implementation involves complex logic or external system interaction, which we want to avoid in a unit test for a class that depends on this service.

  1. Using a Mock
java
1    public class TestPaymentProcessor {
2        @Test
3        public void testPayment() {
4            PaymentService mockPaymentService = mock(PaymentService.class);
5            when(mockPaymentService.processPayment(anyDouble())).thenReturn(true);
6      
7            OrderProcessor processor = new OrderProcessor(mockPaymentService);
8            assertTrue(processor.processOrder(someOrder, 100.00));
9      
10            verify(mockPaymentService).processPayment(100.00);
11        }
12    }

This example in Java uses a mocked PaymentService. The framework used here (commonly Mockito) records how mockPaymentService is used during the test. The test not only checks that the method returns true but also verifies that processPayment was called once with a parameter of 100.00.

When to Use Each?

  • Stubs are generally used when testing the unit's handling of inputs from its dependencies, making sure they can process valid as well as edge case returns.
  • Mocks are more about interaction and less about state. They should be used when it's important to verify that the unit under test interacts correctly with its neighbors (dependencies).

Key Points in a Table

FeatureStubMock
PurposeProvide predefined responsesVerify interactions such as method calls
UsageWhen input behavior needs simulatingWhen verifying specific behaviors or properties
Example FrameworkBasic implementations or libraries like SinonMockito, Sinon with more complex verification
ComplexitySimple, returns dataComplex, involves behavior verification

Summary

Understanding the difference between stubs and mocks is pivotal in correctly structuring unit tests. While stubs help in simulating the behavior of dependencies with fixed data and states, mocks are crucial for validating how the unit under test interacts with them. Effective use of these tools is essential for robust, reliable, and maintainable tests in software development.


Course illustration
Course illustration

All Rights Reserved.