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 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, 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.
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.
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!
noob to master © copyleft