Understanding the difference between stubbing and mocking

When working with unit testing in Java, it is common to use libraries like Mockito to create test doubles that simulate the behavior of dependencies. Two widely used techniques in Mockito are stubbing and mocking. Although they might seem similar at first, they serve different purposes in the testing process. In this article, we will dive into the differences between stubbing and mocking, helping you to understand when to use each technique.

Stubbing

Stubbing is the process of providing pre-defined return values to specific method calls on a test double. This allows you to control the behavior of the dependency and make it return the values you expect during testing. By stubbing, you can create simple and predictable simulations of the dependency.

Consider an example where you have a Calculator class that depends on an Adder interface. To test the Calculator class, you can stub the Adder interface to return specific values when the add() method is called. This way, you can ensure that the Calculator behaves correctly in different scenarios without actually executing the real Adder implementation.

Stubbing can be done using the when() method provided by Mockito, specifying the method to stub and the desired return value. For example:

Adder adder = Mockito.mock(Adder.class);
Mockito.when(adder.add(2, 3)).thenReturn(5);

In this example, all calls to adder.add(2, 3) will return 5. When using stubbing, the original implementation of the method is not executed, making it useful when you only care about the return value and not the actual behavior.

Mocking

Mocking, on the other hand, involves verifying that certain methods on the test double are called during the testing process. It allows you to set expectations on the behavior of the dependency and check if those expectations are met. By mocking, you can ensure that the tested class interacts correctly with its dependencies.

Using the previous example, imagine that the Calculator needs to call the Adder twice during its execution. By mocking the Adder interface, you can specify the expected method calls and their parameters that should occur during the test. If the Calculator fails to make the expected calls, the test will fail, indicating a potential issue.

Mocking can be achieved by using methods like verify() provided by Mockito. For instance:

Adder adder = Mockito.mock(Adder.class);

// Perform some actions on the test subject

Mockito.verify(adder, Mockito.times(2)).add(Mockito.anyInt(), Mockito.anyInt());

In this example, the verify() method checks that the add() method of the Adder interface is called exactly twice, regardless of the specific parameters. If the method is not called or called an unexpected number of times, the test will fail.

When to use stubbing and mocking

Now that we understand the difference between stubbing and mocking, let's look at when to use each technique.

Use stubbing when you only care about the return value of a method and want to simulate different scenarios without executing the actual implementation. Stubbing is useful when you don't want to test the internal behavior of the dependency, but rather the behavior of the class under test.

Use mocking when you want to verify that certain methods are called with specific parameters during the testing process. Mocking is useful when you need to ensure that the tested class interacts correctly with its dependencies, validating the flow of the program.

It's worth noting that Mockito allows using both stubbing and mocking in a single test. Depending on your testing needs, you can combine both techniques to create effective and reliable test cases.

Conclusion

Stubbing and mocking are two fundamental techniques in unit testing with Mockito. While stubbing lets you control the return values of methods, mocking focuses on verifying the interactions with dependencies. By understanding the differences between these techniques and knowing when to use each, you can improve the quality of your tests and ensure the correctness of your code. Happy testing!

© NoobToMaster - A 10xcoder company