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 而失败? 的相关文章

  • 如何在flutter上关注android tv应用程序中的列表视图项目

    我想在 flutter 中构建一个 android 电视应用程序 几乎所有事情都已完成 但一个问题是我无法集中注意力 例如一些弹出效果或边框更改任何告诉用户您现在正在使用此项目的内容 我们在列表视图中迭代的项目 我想要在应用程序中看到的图像
  • 所有侧面的 ElevatedButton 填充不会修改

    我有一个具有以下属性的 ElevatedButton 我在这里附上一张照片 https i stack imgur com oH3pO png https i stack imgur com oH3pO png ElevatedButton
  • 在flutter中跟踪背景位置时使用background_locator插件时出现问题

    我正在尝试使用 flutter 跟踪后台位置 为此我正在使用背景定位器 https pub dev packages background locator插入 它的实现方式是注册某些静态回调函数 我声明了一个 File 类型的类变量来在后台
  • 如何向 firebase.auth() 添加附加信息

    如何向该数据集添加额外的电话号码和地址属性 Firebase 文档似乎没有指定任何相关内容 我已经使用实现了登录 注册和更新firebase auth Login Email Login firebase auth signInWithEm
  • 当应用程序打开时,应用程序未显示接收 FCM 的通知

    当我从 Firebase 发送推送时 如果应用程序在后台或已关闭 我会收到通知 但当应用程序打开时不会 调试我发现它在 MyMessagingService 中特别是在 onMessageReceived 处停止 所以我猜我的问题在于生成通
  • 如何更改或替换 Flutter 中的 ImageCache?

    我想更改 Flutter 应用程序中 ImageCache 的行为 例如 我想尝试不同的驱逐策略 或者 我只是想要零缓存 用于实验 如何替换更改ImageCache 创建一个继承自 WidgetsFlutterBinding 的类 重写该类
  • 如何自动调整 Flutter 中的图标尽可能大

    目前 我正在使用以下代码 body new Container child new Column crossAxisAlignment CrossAxisAlignment stretch mainAxisAlignment MainAxi
  • Flutter - TextPainter 与 Paragraph 绘制书页

    我需要显示长文本 这将占用几个屏幕 页面 我还必须添加一些功能 所以我想实现我自己的文本显示组件 我找到了与此任务相对应的两个类 文本绘制器 use TextSpan对于文本 use 油漆 画布 胶印 用于绘画 段落使用 队列 作为文本和样
  • 新的 FUITableViewDataSource - 如何使用?雨燕3

    刚刚更新到较新的 FirebaseUI Pod 有些事情发生了变化 但其中最大的变化之一是 FUI 表视图的工作方式 我让它在旧版本上运行良好 但在下面遇到了困难 并且缺乏文档 示例 self dataSource FUITableView
  • Flutter 容器的 onTap 方法

    一直在开发一个 flutter 应用程序并根据一些 Firebase 数据动态构建一些容器 我想知道是否有办法获得容器的 onTap 方法 或任何不是按钮的小部件 这是一个代码示例 child new Container INSERT ON
  • 使用 Azure AD B2C 进行 Firebase 身份验证

    我有一个用 xCode Swift 开发的本机 iOS 应用程序 它集成了Firebase 身份验证 https firebase google com docs auth 用于新用户注册和登录的SDK Firebase Auth 系统应链
  • 是否可以将 Cypress e2e 测试与 firebase auth 项目结合使用?

    我正在探索 Cypress 进行 e2e 测试 看起来是很棒的软件 问题在于身份验证 Cypress 文档解释了为什么使用 UI 非常糟糕here https docs cypress io guides getting started t
  • OutputCapture 进行多次测试

    我正在使用 org springframework boot test OutputCapture 来测试记录某些内容的注释 它对于单个测试非常有效 当单独运行测试时 如果源文件中存在使用输出捕获的多个测试 但是当多个测试一起运行时 只有第
  • 如何从 Play WSClient 的字符串创建 WSResponse 对象

    文档 https www playframework com documentation 2 4 x JavaTestingWebServiceClients Mock the web service建议使用模拟Web服务测试基于WSCli
  • 从 SpecFlow 设置 Nunit TimeoutAttribute

    我已经使用 SpecFlow 编写了几个长时间运行的端到端集成测试 但由于 Nunit 超时 它们失败了 将 Timeout x 属性添加到 TestFixture 可以解决问题 但当然每次功能更新时都会被覆盖 如何以 SpecFlow 尊
  • 当 Firebase 函数以 Swift 结束时

    我在我的应用程序中使用 Firebase 它查询大量用户并获取所需的特定数据 但是当它开始查询时 其余功能也继续运行 而不仅仅是查询 所以我无法理解当它结束时 例如在这段代码中 ref observeEventType ChildAdded
  • Flutter - 删除 ListView 中项目之间的空间

    我正在使用 ListView builder 函数来创建项目列表 然而 iOS 中每个项目之间的空间很大 截图 你知道如何删除项目吗 看来是默认的 因为我没有添加它 code 列表显示 return Scaffold body ListVi
  • 如何在 OS X 上的旧版 Safari 中测试我的网站?

    苹果似乎不提供旧版本 Safari 的下载 我什至不确定它们是否会安装在 Mac OS X 上 因为 Safari 似乎是操作系统的一部分 就像 Windows 上的 Internet Explorer 一样 有什么方法可以在旧版本的 Sa
  • 与 White 的集成测试[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 有人有白色框架的经验吗 www co
  • 应用程序关闭时单击 Firebase 通知后打开特定活动/片段

    我知道这个问题似乎重复 但根据我的要求 我在网上搜索了很多帖子 但没有任何对我有用 我的要求 我正在使用 Firebase 来获取推送通知 当应用程序打开时意味着一切正常 但我的问题是 如果有任何推送通知出现 应用程序处于后台 关闭意味着我

随机推荐