Java中紧耦合类的测试问题及代码示例
解决类紧耦合导致无法验证Mock调用的问题
你的问题核心是类间紧耦合:SomeClass在构造函数里直接new SomeApiClass(),完全掌控了依赖对象的创建逻辑,导致测试时没法把这个依赖替换成你Mock出来的someApiClass,自然无法验证它的调用行为。
解决方案:构造函数注入依赖
我们需要把SomeApiClass的创建权从SomeClass内部转移到外部,通过构造函数传入依赖,这样测试时就能轻松传入Mock对象了。
第一步:修改SomeClass的实现
重构构造函数,让依赖的SomeApiClass作为参数传入,而非在内部实例化:
public class SomeClass { private int someProperty; private SomeApiClass apiObject; // 构造函数注入依赖 public SomeClass(int parameter, SomeApiClass apiObject) { this.someProperty = parameter; this.apiObject = apiObject; for(int i=0; i < 2; i++) { apiObject.setApiProperty(i, "Hello World"); } } }
第二步:调整测试代码
现在可以把Mock的SomeApiClass传入SomeClass的构造函数,就能正常验证调用行为了:
@Mock private SomeApiClass someApiClass; private SomeClass someClass; @Before public void setUp() throws Exception { // 将Mock对象传入构造函数 someClass = new SomeClass(3, someApiClass); } @Test public void shouldCreateSomeClass() { // 验证setApiProperty被调用两次,参数符合预期 verify(someApiClass, times(2)).setApiProperty(anyInt(), eq("Hello World")); // 也可以分别验证每一次调用的具体参数 verify(someApiClass).setApiProperty(0, "Hello World"); verify(someApiClass).setApiProperty(1, "Hello World"); }
额外优化建议
如果SomeApiClass是一个具体类,建议进一步定义对应的接口(比如ISomeApi),让SomeClass依赖接口而非具体实现,这样耦合度会更低,扩展性也更强——生产环境用SomeApiClass实现接口,测试环境用Mock实现接口即可。
内容的提问来源于stack exchange,提问作者nit710
相关产品推荐
相关产品推荐

