【问题标题】:How to test async functions that update PublishSubject or BehaviorSubject object (RxDart) in Flutter如何在 Flutter 中测试更新 PublishSubject 或 BehaviorSubject 对象(RxDart)的异步函数
【发布时间】:2019-10-16 13:58:18
【问题描述】:

我已经学习 Flutter 几个星期了,到目前为止我是 Android 背景,我很喜欢它,我也很高兴发现 Flutter 从一开始就考虑到了测试。但是,我在运行以下测试时遇到了问题。

main() => {
  test('test get popular repos', () async {
    final testOwner = Owner(1010, "testLink");
    final testRepo =
        Repo(101, testOwner, "testRepo", "description", 'htmlUrl', 500);
    final testRepoResponse = RepoResponse(List.from([testRepo]), null);
    final uiModel = PopRepo(testRepo.owner.avatarUrl, testRepo.name,
        testRepo.description, "Stars: ${testRepo.stargazersCount}");
    final searchData = SearchData(List.from([uiModel]), null);

    final Repository mockRepository = _mockRepository();

    when(mockRepository.getPopularReposForOrg("org"))
        .thenAnswer((_) => Future.value(testRepoResponse));

    final repoSearchBloc = RepoSearchPageBloc(mockRepository);
    await repoSearchBloc.getPopularRepos("org");


    await expectLater(repoSearchBloc.resultSubject.stream, emits(searchData));
  }),
};

class _mockRepository extends Mock implements Repository {}

我的 RepoSearchBloc 从存储库中获取数据并将其转换为 Ui 模型。最后,它将现在 UI 就绪的数据发布到主题

这是 RepoSearchBloc 中正在测试的方法

getPopularRepos(String org) async {
if (org == null || org.isEmpty)
  return resultSubject.add(SearchData(List(), null));
RepoResponse response = await _repository.getPopularReposForOrg(org);
if (response.error == null) {
  List<Repo> repoList = response.results;
  repoList.sort((a, b) => a.stargazersCount.compareTo(b.stargazersCount));
  var uiRepoList = repoList
      .map((repo) => PopRepo(repo.owner.avatarUrl, repo.name,
          repo.description, "Stars: ${repo.stargazersCount}"))
      .take(3)
      .toList();
  resultSubject.add(SearchData(uiRepoList, null));
} else {
  ErrorState error = ErrorState(response.error);
  resultSubject.add(SearchData(List(), error));
}

当我运行测试时,无论我用 BehaviorSubject 或 PublishSubject 做什么,我都会不断收到此消息:

ERROR: Expected: should emit an event that <Instance of 'SearchData'>
  Actual: <Instance of 'BehaviorSubject<SearchData>'>
   Which: emitted * Instance of 'SearchData'

任何想法如何让这个测试通过?

【问题讨论】:

  • 哪一行报错了?什么是堆栈跟踪?
  • 这是测试await expectLater(repoSearchBloc.resultSubject.stream, emits(searchData));的实际测试功能,而堆栈跟踪是最后的块......真的没有错误只是没有得到预期结果...我不明白为什么流发出自己的对象而不是主题有效负载
  • 如果你要注释掉 expectLater 并用 print(await repoSearchBloc.resultSubject.stream.first); 替换它,它会说什么?

标签: flutter dart rxdart


【解决方案1】:

最终在Flutter Glitter community 的用户 Nico @Rodsevich 的帮助下解决了这个问题

无论如何使用他的建议使用await for

我想出了以下通过的解决方案

    await for (var emittedResult in repoSearchBloc.resultSubject.stream) {
      expect(emittedResult.results[0].repoName, testRepo.name);
      return;
    }

RxDart 库有一些主题测试 for reference,但我被异步发布到的主题不符合他们的测试用例,所以这个解决方案最终正是我所需要的。

当我将 async 移动到预期的参数内时,@Abion47 的评论似乎也能起到作用

expectLater( (await repoSearchBloc.resultSubject.stream.first as SearchData).results[0].repoName, testRepo.name);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 2019-08-04
    • 1970-01-01
    • 1970-01-01
    • 2022-11-10
    相关资源
    最近更新 更多