【问题标题】:Unit Testing On Flutter Firebase functionsFlutter Firebase 函数的单元测试
【发布时间】:2019-04-13 00:40:54
【问题描述】:

美好的一天,我正在尝试对以下在 Cloud Firestore 中创建文档的函数执行一些单元测试。我在我的应用程序中使用了一个函数,它创建了一个文档,但我想编写一个 test.dart 文件,该文件对以下函数执行单元测试,甚至在控制台上打印一些输出以进行验证。

我认为我没有以正确的方式编写我的 Test.dart。我收到一个错误。

createdatabase.dart 文件中的函数

Future<dynamic> createDoc(dataMap,collection) async {
  final TransactionHandler createTransaction = (Transaction tx) async {
    final DocumentSnapshot ds = await tx.get(db.collection(collection).document());
    final Map<String, dynamic> result = {};
    result.addAll(dataMap);
    result['id'] = ds.documentID;
    await tx.set(ds.reference, result);

    return result;
  };

Test.dart

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:test/test.dart';
import '../lib/service/createfirebase.dart';

void main() {
  CreateFirebase cf = new CreateFirebase();   
   //test    
    test('Creating doc on firestore ', () async{ 
      Object dataObj ={'name':'Dev','title':'Dev'};
      var create = await cf.createDoc(dataObj, 'crude');
      expect(true,create);
      print('The doc details are');
      print(dataObj);
    });

}

运行此测试后的错误是 MissingPluginException(在通道 plugins.flutter.io/cloud_firestore 上找不到方法 Firestore#runTransaction 的实现)

但我不明白为什么,因为我拥有所有依赖项,并且如果我在另一个类中调用该函数,则会创建文档。但是在这个测试中调用会出现上述错误。我想我的做法不对。

我可以查看任何有助于测试此类功能的贡献或任何参考资料?

【问题讨论】:

  • 据我了解,插件使用平台特定代码运行,这意味着如果它在 Android 上运行,它将运行 Java/Kotlin 代码。在内部测试中,它不会有任何平台代码可以运行。这使您可以选择在 Firestore 中使用 driver testmock

标签: dart google-cloud-firestore flutter-test


【解决方案1】:

TLDR:mazei513 的评论是正确的。由于 Flutter Firestore 是一个插件而不是一个包,它需要一个平台来运行。例如,该平台可以是 iOS 手机或 Android 虚拟设备。因此,您不能编写 unit 测试来测试 Firestore 命令。您必须使用integration_test 包来执行此类测试。

了解插件与包之间的区别

正如doc 所说,一个插件

是一种特殊的包,它使平台功能 可用于应用程序。可以为 Android 编写插件包 (使用 Kotlin 或 Java)、iOS(使用 Swift 或 Objective-C)、web、macOS、 Windows、Linux 或其任意组合。

如果您查看 /usr/local/flutter/.pub-cache/hosted/pub.dartlang.org/firebase_core-1.7.0 中的 Firestore 插件,您会看到:

jjanvier:nouba$ ls -l /usr/local/flutter/.pub-cache/hosted/pub.dartlang.org/firebase_core-1.7.0                                   
total 48
drwxr-xr-x 4 jjanvier jjanvier  4096 Oct  6 17:20 android
drwxr-xr-x 3 jjanvier jjanvier  4096 Oct  6 17:20 ios
drwxr-xr-x 3 jjanvier jjanvier  4096 Oct  6 17:20 lib
drwxr-xr-x 3 jjanvier jjanvier  4096 Oct  6 17:20 macos
-rw-r--r-- 1 jjanvier jjanvier   912 Oct  6 17:20 pubspec.yaml

由于 Firebase 插件实际上根据平台(Android、iOS、MacOS...)运行本机代码,因此它们需要在“真实”设备上运行。因此,它不适用于flutter test,它只是一个简单的 Dart 执行器。

测试 Firestore 存储库(或命令或查询)

关于设备模拟器

要获得一个可以运行测试的平台,您有多种选择。例如:

  • 从您的 IDE 启动 Android 虚拟设备。这就是我在本地工作时所做的。
  • 在您的持续集成管道上设置 Android 虚拟设备。例如,您 this one 用于 Github 操作。然后你可以在命令行中start the emulator
  • 使用Firebase Test Lab。我没有使用它,但它应该可以工作。

使用 integration_test

关注this documentation为您的项目配置integration_test。不要忘记使用testWidgets 而不是test,因为这样可以在设备模拟器而不是在 Dart 简单环境中启动测试。

完成后,所有集成/端到端测试都可以使用flutter test integration_test 启动。

不要弄乱你的生产数据库

如果您按原样启动命令flutter test integration_test,则测试中存在的文档{'name':'Dev','title':'Dev'} 很有可能会出现在您的生产数据库中。

为了解决这个问题,您主要有两种选择:

  1. 设置一个用于测试的真实 Firebase 项目
  2. 使用Firebase local emulator suite

对于我的项目,我选择了第二个选项。只需一条命令,您就可以启动 Firebase 模拟器、加载设备并运行测试:

firebase --config="firebase.test.json" emulators:exec --import fixtures/ "flutter test integration_test/ --dart-define=FOO=bar"

让我们详细说明一下命令:

  • --config="firebase.test.json" 使用这个配置文件启动 firebase。这允许我在启动测试时保持本地模拟器套件运行
  • --import fixtures/:将文件夹“fixtures”加载为数据集
  • emulators:exec "flutter test integration_test/ --dart-define=FOO=bar":使用 FOO 环境变量启动集成测试

关于模拟/伪造 Firestore

我不建议您模拟或伪造 Firestore,因为这对您而言毫无意义。如果您想测试的是您实际上可以在 Firestore 中正确写入,那么在 Firestore 中使用双精度是没有意义的。

但是,在某些情况下它可能很有用。例如,对在某些时候写入或查询 Firestore 的业务行为进行单元测试。

同样,您有几种解决方案:

  • 您可以自己模拟 Firestore,like it's done here。但是做 IMO 是相当复杂和痛苦的。
  • 您可以使用包fake_cloud_firestore。顾名思义,这是一个完整的 Cloud Firestore 假货。到目前为止,一切都很好,非常适合我。

【讨论】:

    【解决方案2】:

    自从这个问题提交以来已经有一段时间了,但只是为了不让它没有回复。

    当我偶然发现同样的错误时,我发现了这个有用的问题:https://github.com/flutter/flutter/issues/13971

    基本上重新安装所有软件包:

    flutter clean
    flutter packages get
    

    希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 2022-08-04
      • 2018-11-13
      • 1970-01-01
      • 2022-11-04
      • 2023-01-30
      • 2019-04-29
      • 1970-01-01
      • 2021-10-06
      • 2020-01-18
      相关资源
      最近更新 更多