1

我已经学习 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 从 Repository 获取数据并将其转换为 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'

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

4

1 回答 1

0

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

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

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

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

RxDart 库有一些主题测试供参考,但我的主题被异步发布并没有遵守他们的测试用例,所以这个解决方案最终正是我所需要的。

同样@Abion47 的评论似乎也可以在我将 async 移动到参数中以达到预期的效果时

expectLater( (await repoSearchBloc.resultSubject.stream.first as SearchData).results[0].repoName, testRepo.name);
于 2019-05-31T05:45:39.753 回答