如何用Mockito模拟构造函数以获取真实对象实例?
问题背景
我处理单例类时,用Mockito的静态Mock可以正常工作:
public void test() { Foo foo = new Foo(); try (MockedStatic<Foo> staticFoo = mockStatic(Foo.class)) { staticFoo.when(() -> Foo.getFoo()).thenReturn(foo); foo.setVariousValues(); fooManipulator.makeNewFooAndDoStuff(); ... }
但现在需要处理非单例对象(通过new Foo()直接实例化),尝试用Mockito.mockedConstruction时,构造函数返回的是Mockito生成的Mock对象,而我需要返回自己创建的真实Foo对象:
try (MockedConstruction mocked = mockConstruction(Foo.class)) { Foo foo = new Foo(); when(foo.method()).thenReturn("bar"); }
之前用PowerMockito可以实现这个需求:
Foo foo = new Foo(); PowerMockito.whenNew(Foo.class).withNoArguments().thenReturn(foo); foo.setVariousValues(); fooManipulator.makeNewFooAndDoStuff();
想知道这在Mockito新的内联静态Mock中是否可行,还是超出了它的适用范围?
解决方案:Mockito原生实现构造函数返回自定义真实对象
Mockito 3.5.0及以上版本的mockConstruction支持通过自定义Answer拦截构造调用,直接返回你预先创建的真实对象,完全满足需求,不需要依赖PowerMockito。
代码示例:
public void testNonSingleton() { // 提前创建真实Foo对象并设置属性 Foo realFoo = new Foo(); realFoo.setVariousValues(); // 用mockConstruction的重载方法,指定构造调用的返回逻辑 try (MockedConstruction<Foo> mocked = mockConstruction(Foo.class, (mock, context) -> { // 返回我们预先创建的真实对象,而非默认Mock return realFoo; })) { // 此时new Foo()会返回realFoo实例 Foo foo = new Foo(); System.out.println(foo == realFoo); // 输出true fooManipulator.makeNewFooAndDoStuff(); // 后续添加断言验证逻辑 } }
关键说明
- 核心是利用
mockConstruction的Answer参数,自定义构造函数的返回实例,这属于Mockito原生内联Mock的能力范畴,没有超出适用范围。 - 如果需要多次
new Foo()返回不同的真实实例,可以在Answer中根据构造参数或调用次数,动态创建并返回新的真实对象。
内容的提问来源于stack exchange,提问作者Bryan Tan
相关产品推荐
相关产品推荐

