easymock教程
EasyMock is a java based mocking framework, which is used in conjunction with other unit testing frameworks such as JUnit and TestNG. EasyMock is very similar to Mockito mocking framework.
EasyMock是基于Java的模拟框架,可与其他单元测试框架(例如JUnit和TestNG)结合使用。 EasyMock与Mockito模拟框架非常相似。
EasyMock allows us to create mock objects of interfaces and concrete classes and specify their behaviors. Then we can use these mocks to write code to test our main classes. This way writing unit tests are simplified as we don’t need to care about external dependencies.
EasyMock允许我们创建接口和具体类的模拟对象并指定其行为。 然后,我们可以使用这些模拟程序编写代码来测试我们的主类。 这种方式简化了编写单元测试的过程,因为我们不需要关心外部依赖项。
EasyMock (EasyMock)
We can use EasyMock to create mock objects and then inject them into the classes we want to test. However, EasyMock has certain limitations too.
我们可以使用EasyMock创建模拟对象,然后将它们注入到我们要测试的类中。 但是,EasyMock也有某些限制。
- EasyMock can’t mock final and private methods. If these methods are called on mock object, then normal methods will get called. EasyMock不能模拟final和private方法。 如果在模拟对象上调用了这些方法,则将调用普通方法。
- EasyMock provides built-in behavior for equals(), toString(), hashCode() and finalize() methods. It means that we can’t record our own behavior for these methods. EasyMock为equals() ,toString(),hashCode()和finalize()方法提供内置行为。 这意味着我们无法记录这些方法的行为。
EasyMock Maven依赖关系 (EasyMock Maven Dependencies)
We can add the following dependencies to our maven project to use the EasyMock mocking framework.
我们可以将以下依赖项添加到我们的maven项目中,以使用EasyMock模拟框架。
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>3.6</version>
<scope>test</scope>
</dependency>
EasyMock教程 (EasyMock Tutorial)
Let’s create some sample classes and services for mocking. We will use JUnit 5 for writing test cases along with EasyMock for creating mock objects.
让我们创建一些示例类和服务来进行模拟。 我们将使用JUnit 5编写测试用例,并使用EasyMock来创建模拟对象。
package com.journaldev.utils;
public interface Calculator {
int add(int x, int y);
int multiply(int x, int y);
}
package com.journaldev.utils;
public class MathUtils {
private Calculator calc;
public MathUtils(Calculator c) {
this.calc = c;
}
public int add(int i, int j) {
return this.calc.add(i, j);
}
public int multiply(int i, int j) {
return this.calc.multiply(i, j);
}
}
Note that we don’t need to have Calculator implementation for writing our test cases because we are mocking them. This way we can apply the Test-Driven-Development (TDD) model in our application.
请注意,由于我们正在模拟测试用例,因此不需要使用Calculator实现即可编写测试用例。 这样,我们可以在我们的应用程序中应用测试驱动开发(TDD)模型。
Most of the useful methods are provided in the org.easymock.EasyMock
class. Since they are mostly static, we can import them to write fluent and more readable code.
org.easymock.EasyMock
类提供了大多数有用的方法。 由于它们大部分是静态的,因此我们可以将其导入以编写流利且更具可读性的代码。
We can also mock a concrete class and specify its behaviors. Let’s first look at a simple example, where we will mock ArrayList class.
我们还可以模拟一个具体的类并指定其行为。 让我们首先看一个简单的示例,在这里我们将模拟ArrayList类。
package com.journaldev.easymock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.mock;
import static org.easymock.EasyMock.replay;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.ArrayList;
import org.junit.jupiter.api.Test;
public class EasyMockMethodExample {
@Test
public void test() {
ArrayList<Integer> mockList = mock(ArrayList.class);
expect(mockList.add(10)).andReturn(true);
expect(mockList.add(20)).andReturn(true);
expect(mockList.size()).andReturn(2);
expect(mockList.get(0)).andReturn(10);
replay(mockList);
mockList.add(10);
mockList.add(20);
// below will throw exception because it's not mocked
// mockList.add(30);
assertTrue(mockList.get(0) == 10);
assertEquals(mockList.size(), 2);
}
}
Some important points to note from above EasyMock example are:
在EasyMock示例上面需要注意的一些重要点是:
- First step is to create mock object using EasyMock
mock()
method. This method is overloaded where we can specify if we want our mock object to be nice or strict. We can also specify name to be used incase of logging exceptions. We will look into differentMockType
examples in future posts. 第一步是使用EasyMockmock()
方法创建模拟对象。 这个方法是重载的 ,在这里我们可以指定我们想要的模拟对象是好还是严格。 我们还可以指定在记录异常的情况下使用的名称。 在以后的文章中,我们将研究不同的MockType
示例。 - Next step is to stub the behavior and output of a method call using
expect()
andandReturn()
chain statements. 下一步是末梢使用方法调用的行为和输出expect()
和andReturn()
链语句。 - Finally, we have to call
replay()
method to start using stub methods on mock objects. 最后,我们必须调用replay()
方法以开始在模拟对象上使用存根方法。 - If we call a method that is not stubbed, we will get
java.lang.AssertionError
. 如果我们调用未存根的方法,则将得到java.lang.AssertionError
。
EasyMock注释– @ Mock,@ TestSubject (EasyMock Annotations – @Mock, @TestSubject)
EasyMock also provides few annotations to create mock objects.
EasyMock还提供了一些注释来创建模拟对象。
@Mock
: Used to specify a field to be mocked by EasyMock.@Mock
:用于指定EasyMock要模拟的字段。@TestSubject
: Used with a field so that EasyMock will inject mocks created with @Mock on its fields.@TestSubject
:与字段@TestSubject
使用,以便EasyMock将在其字段上注入使用@Mock创建的模拟。
When using annotations, we have to use EasyMockRunner
, EasyMockRule
or EasyMockSupport.injectMocks(Object)
to initialize and inject mock objects. Since we are using JUnit-5, we can’t use EasyMockRunner and EasyMockRule as they are not supported yet. So we will have to use EasyMockSupport.injectMocks(Object)
. We can call this method in @BeforeEach
method.
使用注释时,我们必须使用EasyMockRunner
, EasyMockRule
或EasyMockSupport.injectMocks(Object)
来初始化和注入模拟对象。 由于我们使用的是JUnit-5,因此我们无法使用EasyMockRunner和EasyMockRule,因为它们尚不支持。 因此,我们将不得不使用EasyMockSupport.injectMocks(Object)
。 我们可以在@BeforeEach
方法中调用此方法。
Here is the complete example of mocking objects using EasyMock annotations.
这是使用EasyMock注释模拟对象的完整示例。
package com.journaldev.easymock;
import static org.easymock.EasyMock.*;
import static org.junit.jupiter.api.Assertions.*;
import org.easymock.EasyMockSupport;
import org.easymock.Mock;
import org.easymock.TestSubject;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import com.journaldev.utils.Calculator;
import com.journaldev.utils.MathUtils;
public class EasyMockAnnotationExample {
@Mock
private Calculator mockCalculator;
@TestSubject
private MathUtils mathUtils = new MathUtils(mockCalculator);
@BeforeEach
public void setup() {
EasyMockSupport.injectMocks(this);
}
@Test
public void test() {
expect(mockCalculator.add(1, 1)).andReturn(2);
expect(mockCalculator.multiply(10, 10)).andReturn(100);
replay(mockCalculator);
assertEquals(mathUtils.add(1, 1), 2);
assertEquals(mathUtils.multiply(10, 10), 100);
}
}
EasyMock迭代器样式存根 (EasyMock Iterator Style Stubbing)
We can specify different behaviors for the same method calls by chaining them with times()
. Let’s look at a simple example to understand this clearly.
我们可以通过将它们与times()
链接起来,为相同的方法调用指定不同的行为。 让我们看一个简单的例子来清楚地理解这一点。
//Iterator Style Mocking
reset(mockList);
expect(mockList.size()).andReturn(1).times(2) //return 1 for first 2 calls
.andReturn(2).times(1) //return 2 for 3rd call
.andReturn(4); //return 4 for 4th call
replay(mockList);
assertEquals(mockList.size(), 1);
assertEquals(mockList.size(), 1);
assertEquals(mockList.size(), 2);
assertEquals(mockList.size(), 4);
摘要 (Summary)
EasyMock is a simple tool to create mock objects and write unit tests easily. It’s very similar to Mockito and provides almost the same features as Mockito.
EasyMock是一个简单的工具,可以轻松创建模拟对象并编写单元测试。 它与Mockito非常相似,并提供与Mockito几乎相同的功能。
Reference: Official User Guide
参考: 官方用户指南
easymock教程