如何在颤振中模拟 FirebaseApp

Eds*_*ias 6 unit-testing mocking firebase flutter google-cloud-firestore

我正在尝试测试使用 FirebaseFirestore 的方法,但我无法模拟 FirebaseFirestore.instance 属性。

我正在关注这些例子:

  1. 初始化核心:https : //firebase.flutter.dev/docs/overview#initializing-flutterfire
  2. 使用 firestore 插件:https : //firebase.flutter.dev/docs/firestore/usage

我正在为我的课程使用下面的代码,它运行良好,这意味着 firestoreInstance 已正确加载

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(
    Main(firebaseApp: Firebase.initializeApp()),
  );
}

class Main extends StatelessWidget {
  final Future<FirebaseApp> firebaseApp;
  const Main({this.firebaseApp});

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: firebaseApp,
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.done) {
          final firestoreInstance = FirebaseFirestore.instanceFor(
            app: snapshot.data,
          );
          return MyWidget();
        }
        return CircularProgressIndicator();
      },
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

但是当我运行下面的测试时,我收到了消息:

“以下 FirebaseException 被抛出 building Builder(dirty): [core/no-app] No Firebase App '[DEFAULT]' has been created - call Firebase.initializeApp()”


import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';

class MockFirebaseApp extends Mock implements FirebaseApp {}

void main() {
  FirebaseApp firebaseApp;

  setUp(() async {
    TestWidgetsFlutterBinding.ensureInitialized();
    firebaseApp = MockFirebaseApp();
  });

  group('Main', () {
    testWidgets('Loads my widget', (WidgetTester tester) async {
      await tester.runAsync(() async {
        await tester.pumpWidget(
          Main(firebaseApp: Future.value(firebaseApp)),
        );

        expect(find.byType(CircularProgressIndicator), findsOneWidget);
      });
    });
  });
}

Run Code Online (Sandbox Code Playgroud)

小智 7

我有同样的问题。使用这个答案我找到了解决方案。

  1. https://github.com/FirebaseExtended/flutterfire/blob/master/packages/firebase_auth/firebase_auth/test/mock.dart的内容复制到一个文件中,您可以将其导入到您的测试中,您需要在其中初始化Firebase 应用程序。

  2. setupFirebaseAuthMocks();main所有测试的函数顶部调用。

  3. 在你的setUpAll函数中,调用await Firebase.initializeApp();(你也可以把它放在你的main函数中setupFirebaseAuthMocks();仍然有效)。

现在你应该有一个模拟的 Firebase 应用程序。

这是一个完整的例子:

import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter_test/flutter_test.dart';
import '../lib/authentication/your_auth_using_firebase.dart';
import './mock.dart'; // from: https://github.com/FirebaseExtended/flutterfire/blob/master/packages/firebase_auth/firebase_auth/test/mock.dart



void main() {
  // TestWidgetsFlutterBinding.ensureInitialized(); Gets called in setupFirebaseAuthMocks()
  setupFirebaseAuthMocks();

  setUpAll(() async {
    await Firebase.initializeApp();
  });

  testWidgets('Your Test', (WidgetTester tester) async {
    final YourFirebaseAuthClass authService = YourFirebaseAuthClass();
    // Tests to write
  });
}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,这确实给了我一个良好的开始,但 firebase 消息传递也会抛出 MissingPluginException(在通道 plugins.flutter.io/firebase_messaging 上找不到方法 Messaging#startBackgroundIsolate 的实现) (2认同)

Jos*_*íaz 0

认为这是为了使用 FutureBuilder 作为树的第一个 Widget 或根 Widget,flutter 总是需要一个 MaterialApp 或其他(现在不记得了)。

推荐,重构 FutureBuilder -> Wrap Whit widget -> MaterialApp(home:FutureBuilder(...

并检查 MyWidget() 第一个小部件,也许相同的 MaterialApp 出现错误,但不确定。

如果您使用routes方法进行导航,请使用initialRoute。

运气!