如何测试构造函数私有、通过工厂类创建的Dart类?
测试方案
1. 测试私有构造的Password类
两种可行实现:
- 利用库可见性规则:将测试文件声明为
password.dart所属库的一部分,在测试文件开头添加part of 'package:你的项目路径/password.dart';,即可在测试代码中直接调用Password._()私有构造,独立测试getHashCode、sameAs等方法,不受工厂校验逻辑干扰。 - 用
@visibleForTesting注解开放构造权限:引入meta依赖后,给Password构造函数添加该注解:
import 'package:meta/meta.dart'; class Password extends ValueObject<Password>{ @visibleForTesting const Password._(this.value); // 其余代码不变 }
该注解会让IDE在非测试代码调用该私有构造时抛出警告,既保证正式代码的封装性,又能在测试中直接构造Password实例。
2. Mock PasswordFactory返回Password实例
如果你需要在其他依赖PasswordFactory的类(如Presenter、Controller)的测试中Mock工厂的返回值:
用上述两种方法在测试代码中构造合法的Password实例,直接指定Mock工厂的create方法返回该实例即可,以mockito为例:
import 'package:mockito/mockito.dart'; class MockPasswordFactory extends Mock implements PasswordFactory {} // 测试中使用 final mockFactory = MockPasswordFactory(); final testPassword = Password._('test123'); // 测试环境可直接调用 when(mockFactory.create(any)).thenReturn(testPassword);
part/part of 用法优化建议
你当前的用法符合Dart语法规范,不过针对值对象+工厂的场景,可以做更内聚的调整,省略part/part of的使用:
将工厂逻辑抽象为独立接口,实现类和Password类放在同一个文件即可,既符合依赖倒置原则,也方便上层注入和Mock:
// 抽象工厂接口 abstract class PasswordFactory { Password create(String value); } // 工厂实现类 class DefaultPasswordFactory implements PasswordFactory { const DefaultPasswordFactory(this._spec); final PasswordSpecification _spec; @override Password create(String value) { if(!_spec.isValid(value)) throw Error(); return Password._(value); } } class Password extends ValueObject<Password> { const Password._(this.value); // 其余代码不变 }
该方案既保持了Password构造的私有性,也不需要用part/part of拆分文件,代码逻辑更集中。
内容的提问来源于stack exchange,提问作者Yamin Nather
相关产品推荐
相关产品推荐

