You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dart单元测试报错:预期Future<SignUpResultSuccess>实际为Future<SignUpResult>

问题原因
  • 业务代码中AuthenticationRepository的signUp方法显式声明返回类型为Future<SignUpResult>,即便运行时实际返回的是SignUpResultSuccess或SignUpResultFailure子类实例,方法的静态返回类型依然是父类SignUpResult,直接对比两个Future实例时,泛型静态类型不匹配就会触发你遇到的报错。
  • 测试代码没有正确处理异步逻辑:未将测试函数标记为async,也没有等待异步方法执行完成就直接对比Future实例本身,不符合Flutter异步单元测试的规范。

你当前的业务代码定义是合理的,不需要修改,只要调整测试的断言逻辑即可。

解决方案

有两种常用的修改方案:

方案1:await异步结果后匹配实例值

由于你的SignUpResult子类都继承了Equatable,实例可直接比较值,修改后的测试代码如下:

import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
import 'package:pocket_open_access/app/features/authentication/data/authentication_data_provider.dart';
import 'package:pocket_open_access/app/features/authentication/repository/authentication_repository.dart';

class MockAuthenticationDataProvider extends Mock
    implements AuthenticationDataProvider {}

void main() {
  late AuthenticationRepository authenticationRepository;
  late AuthenticationDataProvider mockAuthenticationDataProvider;
  const String email = 'test@test.com';
  const String password = '1234567';

  setUp(
    () {
      mockAuthenticationDataProvider = MockAuthenticationDataProvider();
      authenticationRepository = AuthenticationRepository(
        authenticationDataProvider: mockAuthenticationDataProvider,
      );
    },
  );
  group(
    'Sign-up user:',
    () {
      test(
        'is successful so returns SignUpResultSuccess()',
        // 测试函数标记为async
        () async {
          when(() => mockAuthenticationDataProvider.createEmailAccount(
                email: any(named: 'email'),
                password: any(named: 'password'),
              )).thenAnswer(
            (_) async {},
          );
          // 等待异步方法执行完成拿到结果
          final result = await authenticationRepository.signUp(email: email, password: password);
          // 直接匹配结果值
          expect(result, const SignUpResultSuccess());
        },
      );
      test(
        'fails so returns SignUpResultFailure with error code',
        // 测试函数标记为async
        () async {
          when(
            () => mockAuthenticationDataProvider.createEmailAccount(
              email: any(named: 'email'),
              password: any(named: 'password'),
            ),
          ).thenThrow(CreateEmailAccountException(errorCode: 'error-code'));
          // 等待异步方法执行完成拿到结果
          final result = await authenticationRepository.signUp(email: email, password: password);
          // 直接匹配结果值
          expect(result, const SignUpResultFailure(errorCode: 'error-code'));
        },
      );
    },
  );
}

方案2:用类型匹配器验证返回类型

如果你只需要验证返回结果的类型,不需要精确匹配字段值,可以用isA匹配器:

// 成功场景验证类型
expect(result, isA<SignUpResultSuccess>());
// 失败场景验证类型+字段
expect(result, isA<SignUpResultFailure>());
expect((result as SignUpResultFailure).errorCode, 'error-code');

内容的提问来源于stack exchange,提问作者Luke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 12:54:04