如何使用Mockito模拟Top类中Bottom对象的实例化?
如何在Top类的单元测试中模拟Bottom对象的创建
嘿,我明白你的问题了——你的Top类在构造方法里直接硬编码new bottom("value"),导致每次测试创建Top时都会实例化真实的Bottom,没法用模拟对象替换对吧?这是典型的依赖硬编码问题,咱们分两种情况来解决:
最优方案:重构Top类,实现依赖注入
首先推荐你重构Top类,把Bottom的实例化控制权交出去,用构造器注入的方式传递依赖。这样既符合面向对象的依赖倒置原则,也让测试变得灵活:
public class top { private final bottom b; // 新增带参构造器:允许外部传入Bottom实例 public top(bottom b) { this.b = b; } // 保留原无参构造器(兼容原有业务代码) public top() { this(new bottom("value")); } }
现在,正常业务代码可以继续用无参构造创建Top,而测试代码可以通过带参构造传入模拟的Bottom对象。
用Mockito编写测试代码
Mockito是Java里最常用的模拟框架,咱们用它来创建Bottom的模拟对象,注入到Top中:
首先确保你的测试依赖里包含Mockito(比如Maven添加mockito-core依赖,Gradle添加testImplementation 'org.mockito:mockito-core:x.x.x'),然后编写测试类:
import org.junit.Test; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.junit.runner.RunWith; @RunWith(MockitoJUnitRunner.class) public class topTest { // 让Mockito自动生成Bottom的模拟对象 @Mock private bottom mockBottom; @Test public void test(){ // 用模拟的Bottom创建Top实例,不会触发真实Bottom的构造 top a = new top(mockBottom); // 如果需要验证Bottom的方法调用,还可以加这样的代码: // verify(mockBottom).someMethodYouExpectToBeCalled(); } }
特殊情况:没法修改Top类怎么办?
如果因为项目限制不能修改Top类的代码,那可以用PowerMock来拦截new bottom("value")的调用,强制返回模拟对象。不过这种方式是“下策”,因为它会绕过Java的正常反射机制,代码耦合度更高:
import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @RunWith(PowerMockRunner.class) @PrepareForTest(top.class) // 告诉PowerMock要处理Top类里的new操作 public class topTest { @Test public void test() throws Exception { // 创建Bottom的模拟对象 bottom mockBottom = PowerMockito.mock(bottom.class); // 拦截所有new bottom("value")的调用,返回咱们的模拟对象 PowerMockito.whenNew(bottom.class).withArguments("value").thenReturn(mockBottom); // 现在创建Top时,会用模拟的Bottom代替真实实例 top a = new top(); } }
总结
优先选择重构代码实现依赖注入,这是更优雅、可维护的方案。只有在完全无法修改原代码的情况下,再考虑用PowerMock这类工具。
内容的提问来源于stack exchange,提问作者Happy
相关产品推荐
相关产品推荐

