Mockito - 在空安全迁移之后存根一个方法

Mockito - stub a method after the null-safety migration

在空安全之前,我可以简单地模拟 sendRequest(...) 方法:

 void stubBaseRepositorySendRequestResponse(String response) {
    when(baseRepository.sendRequest(onGetData: anyNamed('onGetData')))
        .thenAnswer((_) {
      return Future<String>.value(response);
    });
  }

这个方法的签名是:

Future<T> sendRequest<T>({required Future<T> Function() onGetData})

如何使用新的空安全版本的 mockito 完成此操作? 我是否仍然可以保持此存根的通用特性并允许传入任何参数?

这可以通过 mocktail 轻松完成。 更容易,没有 mockito 所需的代码生成。

首先导入 mocktail 很重要:

import 'package:mocktail/mocktail.dart';

然后创建我们要模拟的 class 的模拟:

class MockBaseRepository extends Mock implements BaseRepository {}

void stubBaseRepositorySendRequestResponse(String response) {
when(() => baseRepository.sendRequest(
        onGetData: any(named: 'onGetData', that: isNotNull))).thenAnswer((_) {
      return Future<String>.value(response);
    });
  }

在 mockito 空安全升级后更新存根:

为了概述这个过程,需要生成存根 class,这是使用 build_runner 包完成的。您将需要导入 class 和存根所需的方法。

  1. 更新 class - 从存根定义中删除 'Mock',因为导入的存根 class 将以 'Mock' 开头,例如:

class MyClass extends Mock implements MyClassBase {}

而不是


class MockMyClass extends Mock implements MyClassBase {}
  1. 在 main 之前添加 @GenerateMocks([MockedClass]) 例如 @GenerateMocks([MyClass])(需要导入:import 'package:mockito/annotations.dart';
  2. 安装build_runner
  3. 通过 运行ning
  4. 生成存根 class

flutter pub run build_runner build --delete-conflicting-outputs

  1. 在你的测试文件中导入存根class,它将在你的测试文件相同的目录中生成,导入看起来像import '{TEST_FILE_NAME}.mocks.dart';。现在可以使用存根 class,其名称与 Generate( 中以 Mock 开头的名称相同,例如 MockMyClass
  2. 存根所需方法,在call/assertion之前(提供参数和return值):
    when(mockMyClass.someFancyMethod(any, any))
        .thenAnswer((_) => Future.value(null));

PS

以这种方式模拟 NavigatorObserver 时遇到问题,我得到的错误:

The following MissingStubError was thrown building IconTheme(color: Color(0xdd000000)): 'navigator'

NavigatorState 存根 navigator 没有帮助,我猜这与上下文传播有关。

我使用以下非空安全方式解决了这个问题,如 mockito's null-safety guideline 中所指定:

@GenerateMocks([], 
  customMocks: [
    MockSpec<NavigatorObserver>(returnNullOnMissingStub: true)
  ])

之后运行

flutter pub run  build_runner build --delete-conflicting-outputs

它将通过导入 *.mocks.dart 文件(如上所述)产生 MockNavigatorObserver。当然,因为它是由 mockito 生成的,所以需要删除 class.

的任何自定义定义