Flutter 测试:暂时禁用 Firebase 或以某种方式使测试不会因为 Firebase 而失败?

2024-01-24

我写了一个测试:

homeScreenWidgetsTest() {
  testWidgets('Home page screen widgets', (WidgetTester tester) async {
   
    await tester.pumpWidget(
      MaterialApp(
          home:Provider<AppDatabase>(
              create: (context) => AppDatabase(),
              child: HomePage(),
              dispose: (context, db) => db.close(),
            ),
      ),
    );

    await tester.pumpAndSettle(Duration(seconds: 15));
    expect(find.byType(AppBar), findsOneWidget);
  });
}

它抛出这个错误:

══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following FirebaseException was thrown running a test:
[core/no-app] No Firebase App '[DEFAULT]' has been created - call Firebase.initializeApp()

When the exception was thrown, this was the stack:
#0      MethodChannelFirebase.app (package:firebase_core_platform_interface/src/method_channel/method_channel_firebase.dart:149:5)
#1      Firebase.app (package:firebase_core/src/firebase.dart:55:41)
#2      FirebaseCrashlytics.instance (package:firebase_crashlytics/src/firebase_crashlytics.dart:33:55)
#3      FirebaseLogging.log (package:.../logging/firebase_logging.dart:5:25)
#4      MyClass.work (package:.../oauth/oauth.dart:136:21)
<asynchronous suspension>

错误发生在日志行:

static Future<bool> work() async {
    FirebaseLogging.log("Start work.");

如果我添加Firebase.initializeApp()在我测试的主要方法中:

Future<void> main() async {
  await Firebase.initializeApp();
  homeScreenWidgetsTest();
}

它会抛出这些错误:

package:flutter/src/services/platform_channel.dart 142:86                                       MethodChannel.binaryMessenger
package:flutter/src/services/platform_channel.dart 148:36                                       MethodChannel._invokeMethod
package:flutter/src/services/platform_channel.dart 331:12                                       MethodChannel.invokeMethod
package:flutter/src/services/platform_channel.dart 344:41                                       MethodChannel.invokeListMethod
package:firebase_core_platform_interface/src/method_channel/method_channel_firebase.dart 31:37  MethodChannelFirebase._initializeCore
package:firebase_core_platform_interface/src/method_channel/method_channel_firebase.dart 73:13  MethodChannelFirebase.initializeApp
package:firebase_core/src/firebase.dart 42:47                                                   Firebase.initializeApp
test\home_screen_test.dart 14:18                                                         main

Failed to load "E:\...\home_screen_test.dart": Null check operator used on a null value

所以它会在这一行抛出错误:await Firebase.initializeApp();

如何解决这个问题?提前致谢。

这是 FirebaseLogging.log():

class FirebaseLogging {
  static void log(String log) {
    FirebaseCrashlytics.instance.log(log);
  }
}

当我更新 Firebase 包时,我遇到了同样的问题。

我创建了一个类来交换FirebaseAnalytics具有基于环境的模拟版本。然后更换FirebaseAnalytics与包装类AnalyticsService.

这太老套了,我讨厌它。

如果谁有更好的方法,请分享。

import 'dart:io';

import 'package:firebase_analytics/firebase_analytics.dart';
import 'package:firebase_core/firebase_core.dart';

// The is class is needed because firebase is horrible and apparently hates developers
// - also calling `FirebaseAnalytics.instance` causes tests to fail
class AnalyticsService {
  static get instance => Platform.environment.containsKey('FLUTTER_TEST') ? FakeFirebaseAnalytics() : FirebaseAnalytics.instance;
}

class FakeFirebaseAnalytics implements FirebaseAnalytics {
  @override
  FirebaseApp app;

  @override
  FirebaseAnalyticsAndroid get android => null;

  @override
  Future<void> logAdImpression({String adPlatform, String adSource, String adFormat, String adUnitName, double value, String currency, AnalyticsCallOptions callOptions}) async {}

  @override
  Future<void> logAddPaymentInfo({String coupon, String currency, String paymentType, double value, List<AnalyticsEventItem> items, AnalyticsCallOptions callOptions}) async {}

  @override
  Future<void> logAddShippingInfo({String coupon, String currency, double value, String shippingTier, List<AnalyticsEventItem> items, AnalyticsCallOptions callOptions}) async {}

  @override
  Future<void> logAddToCart({List<AnalyticsEventItem> items, double value, String currency, AnalyticsCallOptions callOptions}) async {}

  @override
  Future<void> logAddToWishlist({List<AnalyticsEventItem> items, double value, String currency, AnalyticsCallOptions callOptions}) async {}

  @override
  Future<void> logAppOpen({AnalyticsCallOptions callOptions}) async {}

  @override
  Future<void> logBeginCheckout({double value, String currency, List<AnalyticsEventItem> items, String coupon, AnalyticsCallOptions callOptions}) async {}

  @override
  Future<void> logCampaignDetails({String source, String medium, String campaign, String term, String content, String aclid, String cp1, AnalyticsCallOptions callOptions}) async {}

  @override
  Future<void> logEarnVirtualCurrency({String virtualCurrencyName, num value, AnalyticsCallOptions callOptions}) async {}

  @override
  Future<void> logEcommercePurchase(
      {String currency,
      double value,
      String transactionId,
      double tax,
      double shipping,
      String coupon,
      String location,
      int numberOfNights,
      int numberOfRooms,
      int numberOfPassengers,
      String origin,
      String destination,
      String startDate,
      String endDate,
      String travelClass}) async {}

  @override
  Future<void> logEvent({String name, Map<String, Object> parameters, AnalyticsCallOptions callOptions}) async {}

  @override
  Future<void> logGenerateLead({String currency, double value, AnalyticsCallOptions callOptions}) async {}

  @override
  Future<void> logJoinGroup({String groupId, AnalyticsCallOptions callOptions}) async {}

  @override
  Future<void> logLevelEnd({String levelName, int success, AnalyticsCallOptions callOptions}) async {}

  @override
  Future<void> logLevelStart({String levelName, AnalyticsCallOptions callOptions}) async {}

  @override
  Future<void> logLevelUp({int level, String character, AnalyticsCallOptions callOptions}) async {}

  @override
  Future<void> logLogin({String loginMethod, AnalyticsCallOptions callOptions}) async {}

  @override
  Future<void> logPostScore({int score, int level, String character, AnalyticsCallOptions callOptions}) async {}

  @override
  Future<void> logPresentOffer({String itemId, String itemName, String itemCategory, int quantity, double price, double value, String currency, String itemLocationId}) async {}

  @override
  Future<void> logPurchase(
      {String currency, String coupon, double value, List<AnalyticsEventItem> items, double tax, double shipping, String transactionId, String affiliation, AnalyticsCallOptions callOptions}) async {}

  @override
  Future<void> logPurchaseRefund({String currency, double value, String transactionId}) async {}

  @override
  Future<void> logRefund({String currency, String coupon, double value, double tax, double shipping, String transactionId, String affiliation, List<AnalyticsEventItem> items}) async {}

  @override
  Future<void> logRemoveFromCart({String currency, double value, List<AnalyticsEventItem> items, AnalyticsCallOptions callOptions}) async {}

  @override
  Future<void> logScreenView({String screenClass, String screenName, AnalyticsCallOptions callOptions}) async {}

  @override
  Future<void> logSearch(
      {String searchTerm,
      int numberOfNights,
      int numberOfRooms,
      int numberOfPassengers,
      String origin,
      String destination,
      String startDate,
      String endDate,
      String travelClass,
      AnalyticsCallOptions callOptions}) async {}

  @override
  Future<void> logSelectContent({String contentType, String itemId}) async {}

  @override
  Future<void> logSelectItem({String itemListId, String itemListName, List<AnalyticsEventItem> items, AnalyticsCallOptions callOptions}) async {}

  @override
  Future<void> logSelectPromotion(
      {String creativeName, String creativeSlot, List<AnalyticsEventItem> items, String locationId, String promotionId, String promotionName, AnalyticsCallOptions callOptions}) async {}

  @override
  Future<void> logSetCheckoutOption({int checkoutStep, String checkoutOption}) async {}

  @override
  Future<void> logShare({String contentType, String itemId, String method}) async {}

  @override
  Future<void> logSignUp({String signUpMethod}) async {}

  @override
  Future<void> logSpendVirtualCurrency({String itemName, String virtualCurrencyName, num value}) async {}

  @override
  Future<void> logTutorialBegin() async {}

  @override
  Future<void> logTutorialComplete() async {}

  @override
  Future<void> logUnlockAchievement({String id}) async {}

  @override
  Future<void> logViewCart({String currency, double value, List<AnalyticsEventItem> items, AnalyticsCallOptions callOptions}) async {}

  @override
  Future<void> logViewItem({String currency, double value, List<AnalyticsEventItem> items}) async {}

  @override
  Future<void> logViewItemList({List<AnalyticsEventItem> items, String itemListId, String itemListName}) async {}

  @override
  Future<void> logViewPromotion({String creativeName, String creativeSlot, List<AnalyticsEventItem> items, String locationId, String promotionId, String promotionName}) async {}

  @override
  Future<void> logViewSearchResults({String searchTerm}) async {}

  @override
  Future<void> resetAnalyticsData() async {}

  @override
  Future<void> setAnalyticsCollectionEnabled(bool enabled) async {}

  @override
  Future<void> setConsent({bool adStorageConsentGranted, bool analyticsStorageConsentGranted}) async {}

  @override
  Future<void> setCurrentScreen({String screenName, String screenClassOverride = 'Flutter', AnalyticsCallOptions callOptions}) async {}

  @override
  Future<void> setDefaultEventParameters(Map<String, Object> defaultParameters) async {}

  @override
  Future<void> setSessionTimeoutDuration(Duration timeout) async {}

  @override
  Future<void> setUserId({String id, AnalyticsCallOptions callOptions}) async {}

  @override
  Future<void> setUserProperty({String name, String value, AnalyticsCallOptions callOptions}) async {}

  @override
  Map get pluginConstants => {};
}

将此 hack 应用于问题中的代码:

class FirebaseLogging {
  static void log(String log) {
    if (Platform.environment.containsKey('FLUTTER_TEST')) return; 
    FirebaseCrashlytics.instance.log(log);
  }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Flutter 测试:暂时禁用 Firebase 或以某种方式使测试不会因为 Firebase 而失败? 的相关文章

  • 空安全 AppLocalization 字符串的最佳方法

    Question 我在用AppLocalizations of context myString在我的 null safe flutter 应用程序中国际化字符串 我的 IDE 告诉我AppLocalizations of context
  • 颤动:所选值不显示在下拉列表中

    我正在从 SQLite 数据库填充城市名称并尝试显示为下拉列表 我通过遵循教程使其工作 但遇到了一个小问题 所选值不会显示在下拉列表中 它继续显示默认提示值 但是 我能够分配和检索正确的选定值 这是我的代码 cities dart clas
  • 无法使用 CLI Firebase auth:import 命令导入用户帐户

    我需要在 Firebase 中导入用户列表以及电子邮件和密码 我正在尝试使用 CLI auth import 命令在 Firebase 中导入用户 https firebase google com docs cli auth import
  • 扑。是否可以更改 TextFormField errorText 填充?

    我在用着TextFormField with OutlineInputBorder 我需要里面的文本在右侧和左侧有填充 为此 我正在使用 contentPadding const EdgeInsets symmetric vertical
  • 出现异常时进行截图

    嘿 有没有一种方法可以在异常 任何异常 时捕获屏幕截图 我的 失败 解决方案位于BaseTestCase unittest TestCase子类 class BaseTestCase unittest TestCase classmetho
  • Firebase Android:电子邮件链接身份验证。意图过滤器不起作用

    我正在为 Android 实现 firebase 电子邮件链接身份验证机制 我已经使用 firebase 指南实现了它 但现在打开电子邮件中的链接后 应用程序始终会进入启动器活动 我无法调试该问题 我还在我的应用程序中实现了动态链接 效果很
  • Lcom/google/firebase/FirebaseApp 类中没有虚拟方法 zzbqo()Z;或其超类(“com.google.firebase.FirebaseApp”的声明

    在我的 Android 应用程序中 编译应用程序时出现错误 我正在最新的 android studio 中工作 并使用 Firebase UI Auth 和 Firebase 数据库 所有版本在应用程序级等级文件中都相同 那么为什么我收到此
  • Android Studio 无法运行 Xcode 模拟器

    我正在尝试使用 Xcode iPhone 模拟器模拟我的 Flutter 应用程序 但收到此错误 在升级 Android Studio 和 Xcode 之前 它运行良好 Launching lib main dart on iPhone X
  • 使用 EditableText 进行 Flutter

    我正在尝试弄清楚如何在 Flutter 中使用 TextEditor 我有 卡片编辑器 基本上我希望能够处理相当于一段文本的内容 new EditableText autofocus true maxLines null backgroun
  • Flutter - 选择 TextFormField 时键盘不显示

    我目前遇到一个问题 当我选择任何一个时 键盘不会出现TextFormFielda 内的小部件Form小部件 这是表单的代码 位于我的内部CreateAccountForm有状态的小部件 import package flutter mate
  • firebase createUser 无需登录[重复]

    这个问题在这里已经有答案了 我的管理员用户可以创建其他用户 但每次创建用户时 我的管理员用户都会注销 新用户会自动登录 有什么方法可以在不登录的情况下创建用户吗 None
  • 绕过 dev/urandom|random 进行测试

    我想编写一个功能测试用例 用已知的随机数值来测试程序 我已经在单元测试期间用模拟对其进行了测试 但我也希望用于功能测试 当然不是全部 最简单的方法是什么 dev urandom仅覆盖一个进程 有没有办法做类似的事情chroot对于单个文件并
  • 在 Flutter 中从 Play 商店获取产品时应用内购买崩溃

    我在安装和实施后遇到问题应用内购买插件 https pub dev packages in app purchaseFlutter 团队提供 到目前为止我做了什么 在 Play 商店中添加了 2 个可见且活跃的产品 提交了用于 alpha
  • AngularFire 访问子元素方法

    我正在寻找一种方法来获取子元素的方法 而不是单独加载该元素 假设我有一个帖子模型 每个帖子都有评论 这就是我获取帖子模型的方式 var post firebase new Firebase FIREBASE URL posts post n
  • 如何在 JMeter 中显示实际循环计数

    我们可以通过以下方式显示实际线程 threadNum 实际循环计数有类似的东西吗 您可以使用 jm Thread Group idx 获取当前循环迭代 jm Thread Group idx 请注意 这是 JMeter 5 中一般增强功能的
  • 如何在 Symfony2 WebTestCase 中重定向后获取当前 URL?

    使用 Symfony2 WebTestCase 我进行了以下测试 client gt request GET this gt assertTrue client gt getResponse instanceof RedirectRespo
  • 未知错误:Chrome 无法启动:异常退出

    当我使用 chromedriver 对 Selenium 运行测试时 出现此错误 selenium common exceptions WebDriverException Message unknown error Chrome fail
  • 向上滚动时固定项目

    所以我有以下屏幕 我正在寻找一种方法 使得当用户向上滚动时 包含进度条和这 4 个数据字段 ItemHeader 的小部件将向上滚动 但搜索容器 SearchTextField 将被固定 到顶部 当然 当用户向下滚动时 它应该重新出现 我找
  • 如何启用 vstest.console.exe 日志记录?

    我试图查看在 Visual Studio 2013 中运行测试时究竟执行了什么 vstest 命令 如何启用 vstest console exe 日志记录 执行的命令是带有相关参数的 VSTest Console exe 当您运行测试时
  • Firebase Firestore:获取文档的生成 ID (Python)

    我可以创建一个新文档 带有自动生成的 ID 并存储对其的引用 如下所示 my data key value doc ref db collection u campaigns add my data 我可以像这样访问数据本身 print d

随机推荐