我有一个方法来测试哪个是调用另一个类来获取一些信息:
public ClassToTest {
public void methodToTest() {
AnotherClass ac = Factory.getInstance();
ResponseObj response = ac.anotherMethod();
}
}
AnotherClass是另一个JAR的一部分,我想模仿它的响应(具体模拟ResponseObj响应)
如何使用Mockito实现这一目标?
答案 0 :(得分:4)
首先,您需要让您的课程可测试。这意味着您需要从AnotherClass ac = Factory.getInstance()
提取对象创建(methodToTest
)到实例字段,或者可能需要单独的方法(以便能够模拟它),甚至更好 - 在类之外创建对象并传递它通过构造函数。因此,您的受测试类应如下所示:
public class ClassToTest {
private AnotherClass ac;
public ClassToTest(AnotherClass ac) {
this.ac = ac;
}
public void methodToTest() {
ResponseObj response = ac.anotherMethod();
response.smth();
}
}
然后,您需要将AnotherClass和ResponseObj声明为测试类中的字段,并将它们初始化为模拟。
AnotherClass ac = Mockito.mock(AnotherClass.class);
ResponseObj responseMock = Mockito.mock(ResponseObj.class);
之后你可以模拟方法调用:
when(anotherClassMock.anotherMethod()).thenReturn(responseMock);
最后,您的测试类应如下所示:
public class ClassToTestTest {
private AnotherClass anotherClassMock = mock(AnotherClass.class);
private ResponseObj responseMock = mock(ResponseObj.class);
private ClassToTest classToTest = new ClassToTest(anotherClassMock);
@Test
public void test() {
when(anotherClassMock.anotherMethod()).thenReturn(responseMock);
classToTest.methodToTest();
verify(responseMock, only()).smth();
}
}
如果您无法更改ClassToTest的公共API,您可以使用Mockito间谍和受保护方法。
public class ClassToTest {
public void methodToTest() {
AnotherClass ac = constructAnotherClassObj();
ResponseObj response = ac.anotherMethod();
response.smth();
}
protected AnotherClass constructAnotherClassObj() {
return Factory.getInstance();
}
}
public class ClassToTestTest {
private AnotherClass anotherClassMock = mock(AnotherClass.class);
private ResponseObj responseMock = mock(ResponseObj.class);
private ClassToTest classToTest = spy(new ClassToTest());
@Test
public void test() {
when(anotherClassMock.anotherMethod()).thenReturn(responseMock);
when(classToTest.constructAnotherClassObj()).thenReturn(anotherClassMock);
classToTest.methodToTest();
verify(responseMock, only()).smth();
}
}
答案 1 :(得分:0)
虽然@arsen_adzhiametov 的 the answer 是正确的,并且达到了标准,但我想贡献我的做法。
在这种情况下,我模拟了 HomeClient
的值,它在内部是一个 WebClient,它为某些值调用另一个服务。
TestClass.java
(请更好地命名)
...
import org.mockito.Mockito;
...
class TestClass {
HomeClient mockHomeClient;
@BeforeEach
void setup() {
mockHomeClient = Mockito.mock(HomeClient.class);
// Axon specific test code. Can ignore if not using Axon.
fixture = new AggregateTestFixture<>(SomeAgreegate.class);
fixture.registerInjectableResource(mockHomeClient);
}
@Test
void testOpenOperation() throws HomeClientException {
Mockito.when(mockHomeClient.getXYZ("nice")).thenReturn(2);
// Do what you will with your code and call the method which you want to test
// Mockito will mock the `HomeClient` in this case and `getXYZ` will return `2`
// You can also change the mock response any time in the same function
Mockito.when(mockHomeClient.getXYZ("nice")).thenReturn(-100);
// Or specify different results on mock when different values are provided
Mockito.when(mockHomeClient.getXYZ("nice")).thenReturn(1);
Mockito.when(mockHomeClient.getXYZ("foo")).thenReturn(100);
Mockito.when(mockHomeClient.getXYZ("bar")).thenReturn(0);
}
}