将 flutter 代码迁移到 null-safety 后,模拟对象不接受 `any`

After migrating flutter code to null-safety, mock objects not accepting `any`

在 Flutter 2 发布后,我已经将我的代码迁移到 sdk: '>=2.12.0 <3.0.0',现在所有代码都是“可靠的空安全”。但是我在 mockito 5.0.0

的单元测试中遇到了错误

例如:

when(mockClient.login(any)).thenThrow(GrpcError.unavailable());

之前没问题,但是现在,编译器在any下显示错误,提示: The argument type 'Null' can't be assigned to the parameter type 'LoginRequest'

我从 mockito 存储库中读取了 this link,但我希望有一种更简单的方法可以像以前一样为带有“不可为空”参数的方法编写测试。

any return null 和 null 值不允许传递给您的 login 方法。

这是 NNBD 的主要缺点,模拟比以前容易得多。

https://github.com/dart-lang/mockito/blob/master/NULL_SAFETY_README.md#problems-with-typical-mocking-and-stubbing

请参阅 您可以使用 mocktail 包,这样会更容易。

使用 mocktail,您的代码将变成

when(() => mockClient.login(any())).thenThrow(GrpcError.unavailable());

给Mock对象赋值时,需要是Mock对象类型,不能是BaseClass


@GenerateMocks(MockSpec<ITransactionRepository>(as: #MockTransactionRepository),
)
void main()
{
    ....
    ITransactionRepository baseObject = MockTransactionRepository();           // wrong
    MockTransactionRepository mockObject = MockTransactionRepository();   // right
    when(baseObject.method(any));     // results in compile error
    when(mockObject.method(any)); // OK
    ...
}

来源:https://github.com/dart-lang/mockito/issues/364

您在模拟 class 中调用的函数,使参数可为空。 如果你在嘲笑这个 class 方法:

class Example {
    String method(String str) {}
}

使字符串参数可为空,例如:

String method(String? str) {}

希望有用。

在 mockito

中处理 null-safety

第 1 步:不要手动创建模拟 classes 和实现,因此删除它们

第 2 步:安装 build_runner 以使用 dart 代码生成文件

第 3 步:import 'package:mockito/annotations.dart'; 到您的测试文件

第 4 步:在 void main() 函数

上方注释要使用 @GenerateMocks([YourClassToBeMocked]) 模拟的目标 class

第 5 步:运行 build_runner 生成带有 --delete-conflicting-outputs 标志的模拟,因此在您的终端类型中:flutter pub run build_runner build --delete-conflicting-outputs。 启用此选项会跳过提示并删除文件。这通常应该用于持续集成服务器和测试,但不用于其他情况。

第 6 步:生成模拟文件后将其导入到您的测试中(它与您的测试文件位于同一目录中)然后您就可以在 where 方法中使用 any 并使用 non-nullable 变量在你的 classes 中,即使没有实现它。

查看完整答案this link