使用 Dart::ffi 在带有本机函数的 flutter 包中测试库函数

Testing Library functions in a flutter package with Native Functions using Dart::ffi

我正在编写 Dart 库以使用 Flutter 访问 C 共享对象。

到目前为止,我创建的示例应用程序(在某种程度上)按预期工作,但我想包括单元测试以保持库的稳定。

详情:

图书馆使用

  static final ffi.DynamicLibrary _liboqs = Platform.isAndroid
      ? ffi.DynamicLibrary.open("liboqs.so")
      : ffi.DynamicLibrary.process();

设置库。

但是当我尝试使用 flutter_test 访问该库时(例如 运行 init 函数 LiboqsFlutter.init() 运行 是一个静态最终 C 本机函数 OQS_init,我得到:

Failed to load "/{HOME DIRECTOR}/liboqs_flutter/test/liboqs_flutter_test.dart": Invalid argument(s): Failed to lookup symbol (dlsym(RTLD_DEFAULT, OQS_init): symbol not found)

我知道 flutter test 无法访问 'main' 资产,但我如何强制通过它,以便正确测试我的代码?

这个issue offers two solutions:

但我不完全理解如何让这些对我有用。颤振驱动程序如何帮助我? #2 代码应该添加到测试中还是原始库中并在测试中调用?如果我在 main/jniLibs 文件夹中已经有预建的共享对象,我真的需要在测试时重建项目吗?这似乎浪费了很多时间来测试应用程序。

Android 工作室中的测试可以通过以下两种方式之一进行。 1) 在 phone 或模拟器环境中或 2) 在桌面上。我正在构建一个 Flutter 包,所以我有一个在 phone 上测试过的示例,以及一个在我的开发环境(桌面)上测试过的 Dart 库。

我要找的配置在桌面上。因此,我需要为我的 (Mac) 环境编译共享对象 (.dylib),将其包含在 build/test 文件夹中,并像这样调用它:

static ffi.DynamicLibrary _open() {
    if (Platform.environment.containsKey('FLUTTER_TEST')) {
      return ffi.DynamicLibrary.open('build/test/{clibrary}.dylib');
    } else {
      return Platform.isAndroid
          ? ffi.DynamicLibrary.open("liboqs.so")
          : ffi.DynamicLibrary.process();
    }
  }

为了完整性,首先检测 OS 然后提供适当的共享对象文件是有意义的。

这将确保您拥有可用于单元测试的共享对象。

flutter 驱动选项使用集成测试来实现相同的目的。我认为添加一些 hacky 代码比添加另一个仅用于测试的依赖项更好。