java 模拟自定义对象
java mocking custom objects
public class MainClass {
public void makeCall() {
CustomObject obj = new CustomObject();
obj.testMethod();
}
}
我想对 makeCall()
进行单元测试。所以我必须模拟上面示例中的 CustomObject
。当我模拟对象 mock(CustomObject.class)
时,我使用 Mockito 作为模拟 framework.But。 makeCall()
方法总是调用实际对象而不是模拟的 one.Is 无论如何模拟本地对象。请帮忙
简短的回答是否定的。你可以做的是将本地对象重构为一个字段或一个参数,如下所示:
public class MainClass {
public void makeCall(CustomObject obj) {
obj.testMethod();
}
}
您当前的程序违反了Dependency Inversion Principle,因此建议您重构它。
如果您使该字段成为一个实例变量,如果您有一个 setter 或您根据构造函数参数对其进行初始化,则可以轻松模拟它。后者的例子:
public class MyTest {
@Mock
private CustomObject objMock;
private MyClass objToTest;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
objToTest = new MyClass(objMock);
}
}
不适用于 Mockito 本身,不。您必须修改代码,以便从另一个来源创建自定义对象并模拟该来源。
这是我推荐的...但是确实存在 PowerMockito:
的解决方案
final CustomObject obj = mock(CustomObject.class);
PowerMockito.whenNew(CustomObject.class).withNoArguments()
.thenReturn(obj);
不过,呃。重构你的代码。你会因此变得更好。
您的 MainClass
的单元测试友好版本应该 CustomObject
注入,例如:
public class MainClass {
private CustomObject customObject = new CustomObject(); // a default one if none is provided
public void setCustomObject(CustomObject customObject) {
this.customObject = customObject;
}
public void makeCall() {
this.customObject.testMethod();
}
}
您的测试将如下所示:
CustomObject mockCustomObject = mock(CustomObject.class);
when(mockCustomObject.testMethod()).thenReturn(...);
MainClass sut = new MainClass();
sut.setCustomObject(mockCustomObject);
sut.makeCall();
verify(mockCustomObject).testMethod();
加上Mockito的注解,可以进一步简化为:
public class MyClassTest {
@InjectMocks
private MainClass mainClass;
@Mock
private CustomObject mockCustomObject;
@Before
public void setup() {
MockitoAnnotations.initMocks(this); // or use mockito runner
}
@Test
public void testMakeCall() {
when(mockCustomObject.testMethod()).thenReturn(...);
mainClass.makeCall();
verify(mockCustomObject).testMethod();
}
}
public class MainClass {
public void makeCall() {
CustomObject obj = new CustomObject();
obj.testMethod();
}
}
我想对 makeCall()
进行单元测试。所以我必须模拟上面示例中的 CustomObject
。当我模拟对象 mock(CustomObject.class)
时,我使用 Mockito 作为模拟 framework.But。 makeCall()
方法总是调用实际对象而不是模拟的 one.Is 无论如何模拟本地对象。请帮忙
简短的回答是否定的。你可以做的是将本地对象重构为一个字段或一个参数,如下所示:
public class MainClass {
public void makeCall(CustomObject obj) {
obj.testMethod();
}
}
您当前的程序违反了Dependency Inversion Principle,因此建议您重构它。
如果您使该字段成为一个实例变量,如果您有一个 setter 或您根据构造函数参数对其进行初始化,则可以轻松模拟它。后者的例子:
public class MyTest {
@Mock
private CustomObject objMock;
private MyClass objToTest;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
objToTest = new MyClass(objMock);
}
}
不适用于 Mockito 本身,不。您必须修改代码,以便从另一个来源创建自定义对象并模拟该来源。
这是我推荐的...但是确实存在 PowerMockito:
的解决方案final CustomObject obj = mock(CustomObject.class);
PowerMockito.whenNew(CustomObject.class).withNoArguments()
.thenReturn(obj);
不过,呃。重构你的代码。你会因此变得更好。
您的 MainClass
的单元测试友好版本应该 CustomObject
注入,例如:
public class MainClass {
private CustomObject customObject = new CustomObject(); // a default one if none is provided
public void setCustomObject(CustomObject customObject) {
this.customObject = customObject;
}
public void makeCall() {
this.customObject.testMethod();
}
}
您的测试将如下所示:
CustomObject mockCustomObject = mock(CustomObject.class);
when(mockCustomObject.testMethod()).thenReturn(...);
MainClass sut = new MainClass();
sut.setCustomObject(mockCustomObject);
sut.makeCall();
verify(mockCustomObject).testMethod();
加上Mockito的注解,可以进一步简化为:
public class MyClassTest {
@InjectMocks
private MainClass mainClass;
@Mock
private CustomObject mockCustomObject;
@Before
public void setup() {
MockitoAnnotations.initMocks(this); // or use mockito runner
}
@Test
public void testMakeCall() {
when(mockCustomObject.testMethod()).thenReturn(...);
mainClass.makeCall();
verify(mockCustomObject).testMethod();
}
}