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

Flutter测试报错:Null类型无法转为Future<Either<Failure, NumberTrival>>

问题分析与解决方案

错误根源

该错误是因为Mockito的方法匹配未命中,导致mock的getConcreteNumberTrival方法返回了默认的Null,而非你定义的right(numberTrival)。常见触发场景包括:

  • 命名参数的匹配格式不符合Mockito要求
  • Mockito版本对Dart空安全支持不足
  • 测试变量的初始化顺序或作用域问题

解决办法

1. 修正Mockito参数匹配逻辑

确保when语句中正确匹配命名参数,使用Mockito提供的匹配器精确命中:

// 精确匹配指定数值
when(mockNumberTrivalRepository.getConcreteNumberTrival(number: eq(tNumber)))
    .thenAnswer((_) async => right(numberTrival));

// 或者匹配任意命名参数(适用于不关心具体数值的场景)
when(mockNumberTrivalRepository.getConcreteNumberTrival(number: anyNamed('number')))
    .thenAnswer((_) async => right(numberTrival));

2. 升级Mockito版本

旧版Mockito对Dart空安全的支持存在缺陷,更新pubspec.yaml中的依赖:

dev_dependencies:
  mockito: ^5.4.0 # 或更高稳定版
  flutter_test:
    sdk: flutter

执行flutter pub get完成依赖更新。

3. 调整变量初始化顺序

将测试变量移至setUp中,确保在测试执行前完成初始化:

void main() {
  late MockNumberTrivalRepository mockNumberTrivalRepository;
  late GetConcreteNumberTrival sut;
  late NumberTrival numberTrival;
  late int tNumber;

  setUp(() {
    mockNumberTrivalRepository = MockNumberTrivalRepository();
    sut = GetConcreteNumberTrival(mockNumberTrivalRepository);
    numberTrival = NumberTrival(text: "text", number: 4);
    tNumber = 4;
  });

  // 测试方法...
}

4. 保持verify与when的参数匹配一致

确保verify语句的参数和when中的匹配规则完全相同:

verify(mockNumberTrivalRepository.getConcreteNumberTrival(number: eq(tNumber)));

完整修正后的测试代码

import 'package:dartz/dartz.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:number_trivia/core/failure/failure.dart';
import 'package:number_trivia/features/number_trivia/domain/entities/number_trival.dart';
import 'package:number_trivia/features/number_trivia/domain/repositories/number_trival_repository.dart';
import 'package:number_trivia/features/number_trivia/domain/usecases/get_concrete_number_trival.dart';

class MockNumberTrivalRepository extends Mock implements NumberTrivalRepository {}

void main() {
  late MockNumberTrivalRepository mockNumberTrivalRepository;
  late GetConcreteNumberTrival sut;
  late NumberTrival numberTrival;
  late int tNumber;

  setUp(() {
    mockNumberTrivalRepository = MockNumberTrivalRepository();
    sut = GetConcreteNumberTrival(mockNumberTrivalRepository);
    numberTrival = NumberTrival(text: "text", number: 4);
    tNumber = 4;
  });

  test("get concrete number trivial", () async {
    when(mockNumberTrivalRepository.getConcreteNumberTrival(number: eq(tNumber)))
        .thenAnswer((_) async => right(numberTrival));

    final result = await sut.execute(tNumber);

    expect(result, right(numberTrival));
    verify(mockNumberTrivalRepository.getConcreteNumberTrival(number: eq(tNumber)));
    verifyNoMoreInteractions(mockNumberTrivalRepository);
  });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 13:02:32