我如何为Flutter方法编写单元测试,并在将来完成?

问题描述 投票:-1回答:1

我正在为Flutter方法编写单元测试,该方法调用async方法然后返回,从而使async在何时何地完成。我的测试“已经完成”后失败。

这是我的测试:

    test('mark as viewed', () {
      final a = Asset();
      expect(a.viewed, false);
      a.markAsViewed();
      expect(a.viewed, true);
    });

这是它正在测试的方法:

  void markAsViewed() {
    viewed = true;
    Repository.get().saveToStorage();
  }

saveToStorage()方法是异步的,我只剩下在后台执行。

我该如何进行这项工作?测试失败告诉我Make sure to use [expectAsync] or the [completes] matcher when testing async code.,但我看不到该怎么做。谁能解释或给我指出正确的文档?当返回的不是Future而是单独完成时,我找不到关于如何处理这些异步的任何信息。

要清楚,此单元测试不是要测试是否将其保存到存储中,而只是将viewed设置为true的基本测试。

已编辑

错误如下:

package:flutter/src/services/platform_channel.dart 319:7  MethodChannel.invokeMethod
===== asynchronous gap ===========================
dart:async                                                _asyncErrorWrapperHelper
package:exec_pointers/asset_details.dart                  Repository.saveToStorage
package:exec_pointers/asset_details.dart 64:22            Asset.markAsViewed
test/asset_details_test.dart 57:9                         main.<fn>.<fn>
This test failed after it had already completed. Make sure to use [expectAsync]
or the [completes] matcher when testing async code.
flutter-test
1个回答
0
投票

此代码与实现方面的关注紧密耦合,这使得很难单独进行测试。

应该重构以遵循具有明确依赖关系的更SOLID设计,可以在进行隔离测试(单元测试)时将其替换掉

例如

class Asset {
    Asset({Repository repository}) {
        this.repository = repository;
    }

    final Repository repository;
    bool viewed;

    void markAsViewed() {
        viewed = true;
        repository.saveToStorage();
    }

    //...
}

通过这种方式测试依赖项的模拟/存根时,可以避免任何不想要的行为。

// Create a Mock Repository using the Mock class provided by the Mockito package.
// Create new instances of this class in each test.
class MockRepository extends Mock implements Repository {}

main() {
  test('mark as viewed', () {
    final repo = MockRepository();
    // Use Mockito to do nothing when it calls the repository
    when(repo.saveToStorage())
      .thenAnswer((_) async => { });

    final subject = Asset(repo);
    expect(subject.viewed, false);
    subject.markAsViewed();
    expect(subject.viewed, true);
    //
    verify(repo.saveToStorage());
  });
}

现在应该可以执行测试,而不会导致依赖项出现意外行为。

© www.soinside.com 2019 - 2024. All rights reserved.