如何Mock方法返回的对象?解决Mock B.foo()返回A对象失败问题
正确Mock B.foo()返回的A对象的方法
你当前的Mock失效核心原因是:SomeClass内部直接new了B实例,你mock的A对象和b.foo()返回的A完全是两个独立实例——Mockito没办法自动把你mock的A关联到内部new出来的B的foo()返回值上。
以下是两种可行的解决方法:
方案1:不修改原代码,拦截B的构造(Mockito 3.5+支持)
利用Mockito的mockConstruction方法拦截B的构造过程,让new出来的B是mock实例,再让这个mock B的foo()返回你预先mock的A对象:
@Test void test() { // 1. Mock A对象并配置其行为 A mockA = Mockito.mock(A.class); Mockito.when(mockA.foo()).thenReturn(something); // 2. 拦截B的构造,返回mock的B实例并配置foo()的返回值 try (MockedConstruction<B> mockedB = Mockito.mockConstruction(B.class, (mock, context) -> { Mockito.when(mock.foo()).thenReturn(mockA); })) { // 3. 执行测试逻辑 SomeClass someClass = new SomeClass(); assertDoesNotThrow(() -> someClass.doSomeThing()); } }
方案2:重构原代码(推荐,让代码更易测试)
修改SomeClass,通过构造方法注入B实例,替代内部new的写法,这样测试时可以直接mock B并指定其foo()的返回值:
修改后的SomeClass代码:
class SomeClass { private final B b; // 构造方法注入B public SomeClass(B b) { this.b = b; } public void doSomeThing() { A a = b.foo(); a.foo(); } }
对应的测试代码:
@Mock B mockB; @Mock A mockA; @InjectMocks SomeClass someClass; @Test void test() { // 配置mockB的foo()返回mockA Mockito.when(mockB.foo()).thenReturn(mockA); // 配置mockA的foo()行为 Mockito.when(mockA.foo()).thenReturn(something); assertDoesNotThrow(() -> someClass.doSomeThing()); }
内容的提问来源于stack exchange,提问作者Rurien
相关产品推荐
相关产品推荐

