面试题答案
一键面试1. 接口方法调用外部服务
- 使用Mockito构建Mock对象:假设存在接口
ExternalServiceInterface
及其方法callExternalService
,在测试调用该接口的类MyService
时,可通过以下代码构建Mock对象。
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import static org.mockito.Mockito.when;
public class MyServiceTest {
@Test
public void testCallExternalService() {
ExternalServiceInterface externalServiceMock = Mockito.mock(ExternalServiceInterface.class);
MyService myService = new MyService(externalServiceMock);
// 设置Mock方法的返回值
when(externalServiceMock.callExternalService()).thenReturn("Mocked Response");
String result = myService.useExternalService();
// 断言结果
assert result.equals("Mocked Response");
}
}
- 避免陷阱:
- Mock对象生命周期管理:确保Mock对象在测试方法内有效。不要在多个测试方法间共享同一个Mock对象实例,除非明确知道这样做的后果。
- Mock方法顺序依赖:Mockito中方法调用顺序通常不影响结果,除非使用了
inOrder
验证。尽量避免在测试中依赖Mock方法调用顺序,使测试更健壮。例如,不要在测试中假设when(mockObj.method1()).thenReturn("a");
必须在when(mockObj.method2()).thenReturn("b");
之前调用。
2. 抽象类方法依赖其他抽象方法
- 使用Mockito构建Mock对象:假设有抽象类
AbstractBase
,其中abstractMethod1
依赖abstractMethod2
,测试其子类MySubClass
。
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import static org.mockito.Mockito.when;
public class MySubClassTest {
@Test
public void testAbstractMethodDependency() {
MySubClass mySubClassMock = Mockito.mock(MySubClass.class, Mockito.CALLS_REAL_METHODS);
// 重写抽象方法并设置返回值
when(mySubClassMock.abstractMethod2()).thenReturn("Mocked Value");
String result = mySubClassMock.abstractMethod1();
// 断言结果
assert result.equals("Expected Result with Mocked abstractMethod2");
}
}
这里使用 Mockito.CALLS_REAL_METHODS
是为了让Mock对象调用真实的抽象类方法,同时Mock掉依赖的抽象方法。
- 避免陷阱:
- Mock对象生命周期管理:与接口类似,保证Mock对象只在当前测试方法内使用。注意如果Mock对象需要继承自抽象类,要确保其初始化和使用都在合适的作用域内。
- Mock方法顺序依赖:同样,尽量避免依赖Mock方法调用顺序。如果必须验证顺序,可以使用
inOrder
方法,但要谨慎使用,因为这会使测试变得脆弱。例如:
import org.junit.jupiter.api.Test;
import org.mockito.InOrder;
import org.mockito.Mockito;
public class MySubClassTest {
@Test
public void testMethodOrder() {
MySubClass mySubClassMock = Mockito.mock(MySubClass.class, Mockito.CALLS_REAL_METHODS);
mySubClassMock.abstractMethod1();
mySubClassMock.abstractMethod2();
InOrder inOrder = Mockito.inOrder(mySubClassMock);
inOrder.verify(mySubClassMock).abstractMethod1();
inOrder.verify(mySubClassMock).abstractMethod2();
}
}
仅在确实需要验证顺序时使用此方法,并且要清楚其对测试稳定性的影响。