如何为密封类的扩展方法创建Mock并解决Mockito的MissingDummyValueError问题
如何为密封类的扩展方法创建Mock并解决Mockito的MissingDummyValueError问题
首先别慌,这个错误其实和你有没有mock unwrap方法没关系——咱们一步步来拆解问题、解决它:
错误本质:Mockito需要类型的默认Dummy值
你看到的MissingDummyValueError,核心原因是Mockito在处理Result<String, Exception>这种自定义泛型类型时,没办法自动生成一个默认的“占位”实例。哪怕你已经显式stub了fetchText的返回值,Mockito内部初始化mock对象时,还是需要这个类型的一个基础dummy值来完成流程。
而你的unwrap是扩展方法,它是静态解析的(编译时就绑定到Result类型上),Mockito根本没法直接mock扩展方法——但其实你也不需要mock它:只要fetchText返回的是正确的Success或Failure实例,unwrap会自然执行对应的逻辑。
解决方案:给Mockito提供Result类型的Dummy值
你只需要在测试代码中,提前注册一个Result<String, Exception>类型的dummy实例即可,用Mockito的provideDummy方法:
方式1:在单个测试中注册
test('execute returns success value when fetchText succeeds', () { // 先注册dummy值 provideDummy<Result<String, Exception>>(const Success(value: 'dummy')); // Arrange when(fetchText()).thenAnswer((_) => const Success(value: 'Success')); // Act final result = execute(); // Assert expect(result, 'Success'); });
方式2:全局注册(所有测试共用)
如果你的测试里多次用到Result<String, Exception>,可以在main函数里用setUpAll一次性注册,避免重复代码:
void main() { setUpAll(() { // 注册该泛型组合的dummy值 provideDummy<Result<String, Exception>>(const Success(value: 'dummy')); // 如果还有其他泛型组合(比如Result<int, Exception>),也需要单独注册 // provideDummy<Result<int, Exception>>(const Success(value: 0)); }); test('execute returns success value when fetchText succeeds', () { // Arrange when(fetchText()).thenAnswer((_) => const Success(value: 'Success')); // Act final result = execute(); // Assert expect(result, 'Success'); }); // 其他测试... }
额外说明
- 选择
Success还是Failure作为dummy值都可以,只要是合法的Result子类实例就行 - 不同的泛型组合(比如
Result<int, CustomException>)需要单独注册dummy值,因为Mockito会把不同泛型参数的类型视为不同的类型 - 你的
execute方法里的as String其实可以去掉:因为fetchText返回Result<String, Exception>,unwrap()在成功时会返回String类型,类型是安全的
备注:内容来源于stack exchange,提问作者sub
相关产品推荐
相关产品推荐

