Flutter - 运行测试时出现多个错误

问题描述

我正在编写我的代码的第一个 flutter 单元测试。测试最初通过,但我收到两个错误:

MissingPluginException(No implementation found for method Auth#registerChangeListeners on channel plugins.flutter.io/firebase_auth)

和:

This test failed after it had already completed. Make sure to use [expectAsync]
or the [completes] matcher when testing async code.

flutter 最近甚至不再使用 flutter_test,而是使用 test 来显着更新测试,这无济于事。我在网上找到的 firebase mock 使用的是 flutter_test

这是完整的错误:

ProviderContainer.read
package:riverpod/…/framework/container.dart:125
ProviderElement.read
package:riverpod/…/framework/base_provider.dart:584
authenticationStatusServiceProvider.<fn>
package:vepo/…/current_authentication_status/current_authentication_status_service.dart:10
ProviderElement._runStateCreate
package:riverpod/…/framework/base_provider.dart:873
ProviderElement.mount
package:riverpod/…/framework/base_provider.dart:801
ProviderContainer.readProviderElement.<fn>
package:riverpod/…/framework/container.dart:308
dart:collection                                                                                                       _HashMap.putIfAbsent
ProviderContainer.readProviderElement
package:riverpod/…/framework/container.dart:287
ProviderContainer.read
package:riverpod/…/framework/container.dart:125
main.<fn>.<fn>
test/…/services/current_authentication_status_service_test.dart:21
2

This test failed after it had already completed. Make sure to use [expectAsync]
or the [completes] matcher when testing async code.
MethodChannel._invokeMethod
package:flutter/…/services/platform_channel.dart:157
===== asynchronous gap ===========================
dart:async                                                                                                            _asyncThenWrapperHelper
MethodChannel.invokeMethod
package:flutter/…/services/platform_channel.dart:332
new MethodChannelFirebaseAuth
package:firebase_auth_platform_interface/…/method_channel/method_channel_firebase_auth.dart:72
MethodChannelFirebaseAuth.delegateFor
package:firebase_auth_platform_interface/…/method_channel/method_channel_firebase_auth.dart:238
new FirebaseAuthPlatform.instanceFor
package:firebase_auth_platform_interface/…/platform_interface/platform_interface_firebase_auth.dart:43
FirebaseAuth._delegate
package:firebase_auth/src/firebase_auth.dart:23
FirebaseAuth.authStateChanges
package:firebase_auth/src/firebase_auth.dart:247
CurrentUserService.onCreate
package:vepo/…/current_user/current_user_service.dart:27
new CurrentUserService
package:vepo/…/current_user/current_user_service.dart:17
currentUserServiceProvider.<fn>
package:vepo/…/current_user/current_user_service.dart:9
ProviderElement._runStateCreate
package:riverpod/…/framework/base_provider.dart:873
ProviderElement.mount
package:riverpod/…/framework/base_provider.dart:801
ProviderContainer.readProviderElement.<fn>
package:riverpod/…/framework/container.dart:308
dart:collection                                                                                                       _HashMap.putIfAbsent
ProviderContainer.readProviderElement
package:riverpod/…/framework/container.dart:287
ProviderContainer.read
package:riverpod/…/framework/container.dart:125
ProviderElement.read
package:riverpod/…/framework/base_provider.dart:584
authenticationStatusServiceProvider.<fn>
package:vepo/…/current_authentication_status/current_authentication_status_service.dart:10
ProviderElement._runStateCreate
package:riverpod/…/framework/base_provider.dart:873
ProviderElement.mount
package:riverpod/…/framework/base_provider.dart:801
ProviderContainer.readProviderElement.<fn>
package:riverpod/…/framework/container.dart:308
dart:collection                                                                                                       _HashMap.putIfAbsent
ProviderContainer.readProviderElement
package:riverpod/…/framework/container.dart:287
ProviderContainer.read
package:riverpod/…/framework/container.dart:125
main.<fn>.<fn>
test/…/services/current_authentication_status_service_test.dart:21
2

✓ CurrentAuthenticationStatusService String.split() splits the string on the delimiter
Exited (1)

[更新] 测试:

import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:test/test.dart';
import 'package:vepo/src/application/services/current_authentication_status/current_authentication_status_service.dart';
import 'package:vepo/src/common/enums/authentication_status_enum.dart';

import 'firebase_mock.dart';

void main() {
  setupCloudFirestoreMocks();

  setUpAll(() async {
    WidgetsFlutterBinding.ensureInitialized();

    await Firebase.initializeApp();
  });
  group('CurrentAuthenticationStatusService',() {
    test('status gets the current authentication status of the user',() async {
      final authenticationStatusService =
          ProviderContainer().read(authenticationStatusServiceProvider);
      authenticationStatusService.status.listen(
        expectAsync1(
          (event) {
            expect(event,AuthenticationStatusEnum.unauthenticated);
          },),);
    });
  });
}

这是被测试的代码:

import 'dart:async';

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:vepo/src/application/services/current_user/current_user_service.dart';
import 'package:vepo/src/common/enums/authentication_status_enum.dart';

final authenticationStatusServiceProvider =
    Provider<CurrentAuthenticationStatusService>((ref) {
  final _authenticationStatuseService =
      CurrentAuthenticationStatusService(ref.read(currentUserServiceProvider));
  ref.onDispose(() => _authenticationStatuseService.onClose());
  return _authenticationStatuseService;
});

/// This service holds the current authentication status of the current user.
class CurrentAuthenticationStatusService {
  CurrentAuthenticationStatusService(this._currentUserService)
      : assert(_currentUserService != null);

  final _authenticationStatusStreamController =
      StreamController<AuthenticationStatusEnum>();
  final CurrentUserService _currentUserService;

  void onClose() => _authenticationStatusStreamController.close();

  Stream<AuthenticationStatusEnum> get status async* {
    // await FirebaseAuth.instance.signOut();
    if (_currentUserService.currentUser.id != null) {
      yield AuthenticationStatusEnum.authenticated;
    } else {
      yield AuthenticationStatusEnum.unauthenticated;
    }
    yield* _authenticationStatusStreamController.stream;
  }
}

我创建了这个测试正在使用的 firebase 模拟:

// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:firebase_core_platform_interface/firebase_core_platform_interface.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';

typedef Callback = void Function(MethodCall call);

dynamic setupCloudFirestoreMocks([Callback customHandlers]) {
  TestWidgetsFlutterBinding.ensureInitialized();

  MethodChannelFirebase.channel.setMockMethodCallHandler((call) async {
    if (call.method == 'Firebase#initializeCore') {
      return [
        {
          'name': defaultFirebaseAppName,'options': {
            'apiKey': '123','appId': '123','messagingSenderId': '123','projectId': '123',},'pluginConstants': <String,dynamic>{},}
      ];
    }

    if (call.method == 'Firebase#initializeApp') {
      return <String,dynamic>{
        'name': call.arguments['appName'],'options': call.arguments['options'],};
    }

    if (customHandlers != null) {
      customHandlers(call);
    }

    return null;
  });
}

知道为什么会出现错误吗?在运行第二个单元测试时,我也得到了相同的结果。测试看起来几乎没有问题,因为它是相同的错误并且两个测试都通过了。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...