如何使用 EasyMock 模拟由另一个方法调用的方法?
How to mock a method which is called by another method using EasyMock?
我需要在 void 方法中模拟一个方法。
这是我的示例代码:
class MyClass {
public MyClass(Session s, Boolean b1, Boolean b2)
void myMethod(some paramaters...) {
// some code
int count= setSize();
}
int setSize() {
// some calculation....
return size;
}
现在在我的测试中 class 我想模拟 setSize()
到 return 我自己的价值说 300
.
我喜欢:
MyClass mockclass = createNiceMock(MyClass.class);
EasyMock.expect(mockimplyZero.setBatchSize()).andReturn(Integer.valueOf(300));
mockclass.myMethod(parameters....)
当调用 myMethod
时,它没有正确地进入方法。
我认为可能是 EasyMock 正在为 MyClass
构造函数设置默认值。如何正确模拟?
MyClass
中没有方法,除了构造函数、myMethod
和 setSize
您不应该在 same class 上测试另一个方法时模拟 one 方法。理论上你可以这样做(使用 Mokito spy
例如)。
从这个意义上说,您在错误的层面上接近了这个:您实际上不应该关心您的测试方法在您的 class 测试中调用了哪些其他方法。但是如果你必须调整测试的东西,那么要走的路(例如)是一种允许你的测试代码在调用 mymethod()
之前设置 size 字段的方法.
或者:您将关注点分开,然后将 "size" 部分移动到它自己的 class X 中。然后您的 class 被测试可以包含 X 的实例;然后可以模拟该实例。
长话短说:您想退一步阅读一些有关如何使用 EasyMock 的教程。这不是你可以通过反复试验来学习的东西。
您可以使用部分模拟来完成。这是一个接近您的代码的示例。
首先测试class。您将需要创建它的部分模拟。 getSize
应该被模拟,但是 myMethod
应该被模拟,因为它是经过测试的方法。
此外,您经常需要调用构造函数来正确初始化 class(classical mock 不会调用任何构造函数)。
class MyClass {
private boolean b1;
private boolean b2;
public MyClass(boolean b1, boolean b2) {
this.b1 = b1;
this.b2 = b2;
}
int myMethod() {
return getSize();
}
int getSize() {
return 42;
}
public boolean getB1() {
return b1;
}
public boolean getB2() {
return b2;
}
}
然后测试如下
import org.junit.Test;
import static org.easymock.EasyMock.*;
import static org.junit.Assert.*;
public class MyClassTest {
@Test
public void test() {
// Create a partial mock by calling its constructor
// and only mocking getSize
MyClass mock = createMockBuilder(MyClass.class)
.withConstructor(true, true)
.addMockedMethod("getSize")
.createMock();
// Record that getSize should return 8 (instead of 42)
expect(mock.getSize()).andReturn(8);
// All recording done. So put the mock in replay mode
replay(mock);
// Then, these assertions are to prove that the partial mock is
// actually doing what we expect. This is just to prove my point. Your
// actual code will verify that myMethod is doing was is expected
// 1. Verify that the constructor was correctly called
assertEquals(true, mock.getB1());
assertEquals(true, mock.getB2());
// 2. Verify that getSize was indeed mocked
assertEquals(8, mock.myMethod());
// Check everything expected was indeed called
verify(mock);
}
}
工作完成。请注意,这不一定是糟糕设计的标志。我经常在测试 Template method pattern.
时使用它
我需要在 void 方法中模拟一个方法。
这是我的示例代码:
class MyClass {
public MyClass(Session s, Boolean b1, Boolean b2)
void myMethod(some paramaters...) {
// some code
int count= setSize();
}
int setSize() {
// some calculation....
return size;
}
现在在我的测试中 class 我想模拟 setSize()
到 return 我自己的价值说 300
.
我喜欢:
MyClass mockclass = createNiceMock(MyClass.class);
EasyMock.expect(mockimplyZero.setBatchSize()).andReturn(Integer.valueOf(300));
mockclass.myMethod(parameters....)
当调用 myMethod
时,它没有正确地进入方法。
我认为可能是 EasyMock 正在为 MyClass
构造函数设置默认值。如何正确模拟?
MyClass
中没有方法,除了构造函数、myMethod
和 setSize
您不应该在 same class 上测试另一个方法时模拟 one 方法。理论上你可以这样做(使用 Mokito spy 例如)。
从这个意义上说,您在错误的层面上接近了这个:您实际上不应该关心您的测试方法在您的 class 测试中调用了哪些其他方法。但是如果你必须调整测试的东西,那么要走的路(例如)是一种允许你的测试代码在调用 mymethod()
之前设置 size 字段的方法.
或者:您将关注点分开,然后将 "size" 部分移动到它自己的 class X 中。然后您的 class 被测试可以包含 X 的实例;然后可以模拟该实例。
长话短说:您想退一步阅读一些有关如何使用 EasyMock 的教程。这不是你可以通过反复试验来学习的东西。
您可以使用部分模拟来完成。这是一个接近您的代码的示例。
首先测试class。您将需要创建它的部分模拟。 getSize
应该被模拟,但是 myMethod
应该被模拟,因为它是经过测试的方法。
此外,您经常需要调用构造函数来正确初始化 class(classical mock 不会调用任何构造函数)。
class MyClass {
private boolean b1;
private boolean b2;
public MyClass(boolean b1, boolean b2) {
this.b1 = b1;
this.b2 = b2;
}
int myMethod() {
return getSize();
}
int getSize() {
return 42;
}
public boolean getB1() {
return b1;
}
public boolean getB2() {
return b2;
}
}
然后测试如下
import org.junit.Test;
import static org.easymock.EasyMock.*;
import static org.junit.Assert.*;
public class MyClassTest {
@Test
public void test() {
// Create a partial mock by calling its constructor
// and only mocking getSize
MyClass mock = createMockBuilder(MyClass.class)
.withConstructor(true, true)
.addMockedMethod("getSize")
.createMock();
// Record that getSize should return 8 (instead of 42)
expect(mock.getSize()).andReturn(8);
// All recording done. So put the mock in replay mode
replay(mock);
// Then, these assertions are to prove that the partial mock is
// actually doing what we expect. This is just to prove my point. Your
// actual code will verify that myMethod is doing was is expected
// 1. Verify that the constructor was correctly called
assertEquals(true, mock.getB1());
assertEquals(true, mock.getB2());
// 2. Verify that getSize was indeed mocked
assertEquals(8, mock.myMethod());
// Check everything expected was indeed called
verify(mock);
}
}
工作完成。请注意,这不一定是糟糕设计的标志。我经常在测试 Template method pattern.
时使用它