1. Overview
1.概述
Mocking frameworks are used to mock interaction with dependencies so as to test our classes in isolation. Typically, we mock the dependencies to return the various possible values. This way, we can ensure our class can handle each of those values.
嘲弄框架用于嘲弄与依赖关系的交互,以便在隔离状态下测试我们的类。通常情况下,我们模拟依赖关系来返回各种可能的值。这样,我们可以确保我们的类可以处理每一个值。
But, sometimes we might have to mock dependency methods that do not return anything.
但是,有时我们可能不得不模拟那些不返回任何东西的依赖性方法。
In this tutorial, we will see when and how to mock void methods using EasyMock.
在本教程中,我们将看到何时以及如何使用EasyMock来模拟void方法。
2. Maven Dependency
2.Maven的依赖性
First, let’s add the EasyMock dependency to our pom.xml:
首先,让我们将EasyMock依赖性添加到我们的pom.xml。
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>4.0.2</version>
<scope>test</scope>
</dependency>
3. When to Mock a void Method
3.何时模拟一个void方法?
When we test classes with dependencies, we would normally want to cover all values returned by the dependency. But sometimes, the dependency methods do not return a value. So, if nothing is returned, why would we want to mock a void method?
当我们测试有依赖关系的类时,我们通常希望涵盖依赖关系所返回的所有值。但有时,依赖关系的方法并不返回值。所以,如果没有返回任何东西,我们为什么要模拟一个void方法?
Even though void methods do not return a value, they might have side-effects. An example of this is the Session.save() method. When we save a new entity, the save() method generates an id and sets it on the entity passed.
即使无效方法不返回一个值,它们也可能有副作用。 这方面的一个例子是Session.save()方法。当我们保存一个新的实体时,save()方法会生成一个id并将其设置在所传递的实体上。
For this reason, we have to mock the void method to simulate the various processing outcomes.
由于这个原因,我们必须模拟无效方法来模拟各种处理结果。
Another time the mocking might come in handy is when testing exceptions thrown by the void method.
另一个时候,嘲讽可能会派上用场,就是在测试由void方法抛出的异常时。
4. How to Mock a void Method
4.如何模拟一个void方法?
Now, let’s see how we can mock a void method using EasyMock.
现在,让我们看看如何使用EasyMock来模拟一个无效方法。
Let’s suppose, we have to mock the void method of a WeatherService class that takes a location and sets the minimum and maximum temperature:
让我们假设,我们必须模拟一个WeatherService类的void方法,它需要一个位置并设置最低和最高温度。
public interface WeatherService {
void populateTemperature(Location location);
}
4.1. Creating the Mock Object
4.1.创建模拟对象
Let’s start by creating a mock for the WeatherService:
让我们先为WeatherService创建一个模拟。
@Mock
private WeatherService mockWeatherService;
Here, we’ve done this using the EasyMock annotation @Mock. But, we can do this using the EasyMock.mock() method as well.
在这里,我们使用EasyMock注解@Mock来完成。但是,我们也可以使用EasyMock.mock()方法来做到这一点。
Next, we’ll record the expected interactions with the mock by calling populateTemperature():
接下来,我们将通过调用populateTemperature()来记录与模拟的预期互动。
mockWeatherService.populateTemperature(EasyMock.anyObject(Location.class));
Now, if we don’t want to simulate the processing of this method, this call itself is sufficient to mock the method.
现在,如果我们不想模拟这个方法的处理过程,这个调用本身就足以模拟这个方法。
4.2. Throwing an Exception
4.2.抛出一个异常
First, let’s take the case where we want to test whether our class can handle exceptions thrown by the void method. For this, we’ll have to mock the method in such a way that it throws these exceptions.
首先,让我们来看看我们想测试我们的类是否能处理由void方法抛出的异常的情况。为此,我们必须对该方法进行模拟,以使其抛出这些异常。
In our example, the method throws ServiceUnavailableException:
在我们的例子中,该方法抛出了ServiceUnavailableException。
EasyMock.expectLastCall().andThrow(new ServiceUnavailableException());
As seen above, this involves simply calling the andThrow(Throwable) method.
如上所示,这涉及到简单地调用andThrow(Throwable)方法。
4.3. Simulating Method Behavior
4.3.模拟方法的行为
As mentioned earlier, we might sometimes need to simulate the behavior of the void method.
如前所述,我们有时可能需要模拟无效方法的行为。。
In our case, this would involve populating the minimum and maximum temperatures of the locations passed:
在我们的案例中,这将涉及填充所通过的地点的最低和最高温度。
EasyMock.expectLastCall()
.andAnswer(() -> {
Location passedLocation = (Location) EasyMock.getCurrentArguments()[0];
passedLocation.setMaximumTemparature(new BigDecimal(MAX_TEMP));
passedLocation.setMinimumTemperature(new BigDecimal(MAX_TEMP - 10));
return null;
});
Here, we’ve used the andAnswer(IAnswer) method to define the behavior of the populateTemperature() method when called. Then, we’ve used the EasyMock.getCurrentArguments() method – that returns the arguments passed to the mock method – to modify the locations passed.
在这里,我们使用了andAnswer(IAnswer)方法来定义populateTemperature()方法被调用时的行为。然后,我们使用了EasyMock.getCurrentArguments()方法–它返回传递给模拟方法的参数–来修改传递的位置。
Note that we have returned null at the end. This is because we are mocking a void method.
请注意,我们在结尾处返回了null。这是因为我们正在模拟一个无效方法。
It’s also worth noting that this approach is not restricted to mocking void methods only. We can also use it for methods that return a value. There, it comes in handy when we want to mock the method to return values based on the arguments passed.
值得注意的是,这种方法并不只限于嘲弄无效方法。我们也可以把它用于返回一个值的方法。在这里,当我们想根据传递的参数来模拟方法返回值时,它就会派上用场。
4.4. Replaying the Mocked Method
4.4.重放模拟的方法
Lastly, we’ll use the EasyMock.replay() method to change the mock to “replay” mode, so that the recorded actions can be replayed when called:
最后,我们将使用EasyMock.replay()方法,将mock改为 “replay “模式,以便在调用时可以重放记录的动作。
EasyMock.replay(mockWeatherService);
Consequently, when we call the test method, the custom behavior defined should be executed.
因此,当我们调用测试方法时,定义的自定义行为应该被执行。
5. Conclusion
5.结论
In this tutorial, we saw how to mock void methods using EasyMock.
在本教程中,我们看到了如何使用EasyMock来模拟无效方法。
And of course, the code used in this article can be found over on GitHub.
当然,本文中使用的代码可以在GitHub上找到,。