使用 Flutter 测试特定状态 bloc_test

Testing for specific states using Flutter bloc_test

我正在尝试测试使用 BloC 模式和 bloc_test 发出的特定值。目前,当我预期失败时,我能够进行通过测试。 bloc_test 必须只检查发出的状态类型而不是特定值。有没有办法使用 bloc_test 包来测试我们发射状态的特定值?

group('[NewsArticleBloc]', () {
    NewsArticleBloc sut;
    MockNewsRepo mockNewsRepo;
    setUp(() {
      mockNewsRepo = new MockNewsRepo();
      sut = NewsArticleBloc(newsRepo: mockNewsRepo);
    });

    tearDown(() => sut.close());

    blocTest(
      'Next state check',
      build: () => sut,
      act: (bloc) {
        when(mockNewsRepo.getTopHeadlines())
            .thenAnswer((_) => Future.value([Article(author: 'Josh')]));
        bloc.add(GetTopHeadlines());
      },
      expect: [
        TopHeadlines(topHeadlines: [Article(author: 'Micheal')])
                                             //Expecting failure here ^
      ], 
    );
  });
 

如果您乐于使用预发布版本:8.0.0-nullsafety.0,您可以将预期状态传递到 blocTest 中的 expect,或者您可以传递一个 Matcher就像在常规 Dart/Flutter 测试中一样:

// note expect now requires a function that produces a list
expect: () => [
  TypeMatcher<TopHeadlines>(),
]

如果发出的第一个状态的类型为:TopHeadlines,这将成功。如果除了类型之外还想验证状态的一些属性,还可以使用:

expect: () => [
  TypeMatcher<TopHeadlines>()
    .having((headlines) => headlines.topHeadlines, 'topHeadlines', hasLength(1)) 
    .having((headlines) => headlines.otherProperty, 'otherProperty', isNotNull)
]

如果您不能在您的应用中使用预发布版本,Bloc 扩展 Stream,因此您可以使用常规流测试方法来验证正确的行为:

final bloc = ...
final firstStateEmitted = bloc.skip(1).first;  // skip initialState then return the next state
expect(firstStateEmitted, isA<TopHeadlines>());
expect(firstStateEmitted.someProperty, isNotNull);