Table of contents
1.
Introduction
2.
Mock
3.
Stub
4.
Spy
5.
Difference Between Mock, Stub, and Spy
6.
Frequently Asked Questions
6.1.
What is the difference between mock and spy?
6.2.
What is the difference between fake and spy?
6.3.
What are test doubles in unit testing?
6.4.
What is the difference between @autowired and @mock?
6.5.
What is mock in Spock?
7.
Conclusion
Last Updated: Apr 17, 2024
Easy

Mock vs Stub vs Spy

Author Aman Thakur
0 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

This article discusses the difference between mock, stub, and spy. We'll show what the framework offers in terms of interaction-based testing.

Spock is a Java and Groovy testing framework that helps automate the manual testing of software applications. It offers its mocks, stubs, and spies and built-in capabilities for tests that would otherwise necessitate the use of third-party libraries.

Mock vs Stub vs Spy

Mock

Mocks are objects that keep track of method calls. The dynamic wrappers for dependencies used in the tests were referred to as this. It's used to keep track of and verify how Java classes interact. The test doubles' most powerful and versatile form is known as a mock.We employ a mocking technique named mock().

The fundamental benefit of mocks is that they provide complete control over the behaviour of mimicked objects. Mock objects are frequently used for behaviour testing. Checking the right methods and pathways that are applied to the objects is referred to as behavior.

The functions of using mocks in software testing include simulating behavior or responses of dependencies, isolating code under test from external systems, and enabling controlled testing of specific scenarios without relying on real components or external resources. Mocks facilitate faster, more focused, and deterministic testing by providing predictable responses and reducing dependencies on complex or unreliable external systems.

Mocks are often constructed using a library or mocking framework such as Mockito, JMock, or EasyMock. It's used to test a huge number of tests when stubs aren't enough. One of the most important features of mock is that it allows us to check how many times a certain method is called.

The use of mock() is demonstrated in the following code snippet.

#include <gtest/gtest.h>
#include <gmock/gmock.h>

// Define a simple interface
class DatabaseInterface {
public:
    virtual int getValue(int key) const = 0;
};

// Define a mock implementation of the interface
class MockDatabase : public DatabaseInterface {
public:
    MOCK_CONST_METHOD1(getValue, int(int key));
};

// Function under test
int fetchData(DatabaseInterface& db, int key) {
    return db.getValue(key);
}

// Test case using mock
TEST(MockTest, FetchDataTest) {
    MockDatabase mockDb; // Create a mock object
    EXPECT_CALL(mockDb, getValue(42)).WillOnce(testing::Return(100)); // Define behavior of mock

    int result = fetchData(mockDb, 42); // Call function under test
    EXPECT_EQ(result, 100); // Verify result
}

int main(int argc, char** argv) {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

Explanation: We define a simple interface DatabaseInterface with a method getValue() to retrieve values from a database. We create a mock implementation MockDatabase using Google Mock (gmock) library, which overrides the getValue() method. In the test case FetchDataTest, we create an instance of MockDatabase, define the expected behavior using EXPECT_CALL, and specify the return value. We then call the fetchData() function with the mock object as a parameter and verify the result using EXPECT_EQ.

Stub

Stubs are test-response objects containing specified data and utilising it to provide replies. In other terms, a stub is a test object that looks like a genuine object but only has the bare minimum of methods. We use stubs when we don't want to utilise objects that might respond with actual data. The test doubles' lightest and most static form is known as a stub.

The stubs' primary functions are as follows:
1. Regardless of the input, it always returns the predetermined result.
2. It may be used to make database objects seem like this.
3. Stubs are used to simplify the complications that arise during the construction of actual things. They're most commonly used for state verification.

Spy

Partially mocked objects are known as spies. A spy builds a partial object or a half-dummy of the real thing by stubbing or spying the genuine ones. The genuine item is not spied on; rather, we spy on certain of its specialised processes. To put it another way, we take an existing (actual) object and change or spy on only a portion of its methods.

When we have a large class with a lot of methods and we want to imitate some of them, spies come in handy. We should use spies instead of mocks and stubs in this circumstance. If the methods aren't stubbed, it invokes the true method behaviour.

The spy() function in Mockito is used to create spy objects. It enables us to use the real object's usual methods. The spy() function is demonstrated in the following code sample. However, there are times when we need to deal with legacy code. It may be difficult to test old code with Mocks or Stubs. Spies may be the only realistic choice in this instance.

The use of the spy() method is demonstrated in the following code snippet.

import org.junit.Test;
import org.mockito.Mockito;

import java.util.ArrayList;
import java.util.List;

import static org.junit.Assert.assertEquals;

public class ExampleTest {

    @Test
    public void testSpy() {
        // Create a spy of the ArrayList class
        List<String> list = new ArrayList<>();
        List<String> spyList = Mockito.spy(list);

        // Add elements to the spy list
        spyList.add("one");
        spyList.add("two");

        // Verify that elements were added to the spy list
        assertEquals(2, spyList.size());

        // Mock behavior of the spy list
        Mockito.when(spyList.size()).thenReturn(10);

        // Verify that the mock behavior is applied
        assertEquals(10, spyList.size());
    }
}

Explanation: We create a spy of the ArrayList class using the spy() method provided by Mockito. We add elements to the spy list and verify that they were added correctly. We then mock the behavior of the spy list using Mockito.when() to override the size() method. Finally, we verify that the mock behavior is applied by checking the size of the spy list.

Difference Between Mock, Stub, and Spy

ParameterMockStubSpy
PurposeSimulate behaviorProvide canned responsesTrack interactions, partial mock
CreationBy creating a class instanceBy extending a class or implementing an interfaceBy creating a class instance
InteractionVerifies method callsDoes not verify method callsTracks method calls
Methods OverrideAll methods must be mockedOnly required methods need to be stubbedMethods can be overridden selectively
UsageUsed when testing interactions between objectsUsed when testing behavior based on inputUsed when partial mocking is needed or to verify interactions

Must see, Difference Between Structure and Union

Frequently Asked Questions

What is the difference between mock and spy?

Mock objects replace real objects and simulate behavior, verifying interactions between objects in unit tests. Spy objects are real objects with instrumentation to track method calls, retaining original behavior while observing interactions.

What is the difference between fake and spy?

Fakes are simplified implementations of real objects used in testing to mimic behavior and replace actual dependencies. Spies are real objects instrumented to track interactions, allowing observation of method calls while retaining original behavior.

What are test doubles in unit testing?

Test doubles in unit testing are objects that mimic the behavior of real components (such as classes, modules, or services) within the system under test. They are used to isolate the code being tested by replacing dependencies with controlled implementations. 

What is the difference between @autowired and @mock?

The spy method is a Mockito feature that allows you to partially spoof an object. When utilising the spy technique, an actual object is produced, and spies or stubs of that real object are constructed. If we don't stub a method with a spy, it will invoke the true method behaviour.

What is mock in Spock?

We don't need a separate library or framework for Mock support because mocking is integrated into Spock.Concrete classes can also be simulated. If you're used to other mocking frameworks, you might think that you can only spoof Java interfaces, however, Spock allows us to generate a mock from a concrete class.

Conclusion

If you have reached till here that means you really enjoyed reading this article. Hence, this article thoroughly described spies, mocks, and stubsKnowledge on this subject will make our tests faster, more reliable, and easier to read.

We hope that this blog has helped you enhance your knowledge regarding the key differences between mock, stub and spy. Do upvote our blog to help other ninjas grow. You might be interested in articles such as Fundamentals of Software Testing. If that is not enough you can just head over to our practice platform Coding Ninjas Studio to practise top problems, attempt mock tests, read interview experiences, and much more. If you like this article do consider to upvote it.

Happy Learning!

Live masterclass