【问题标题】:FLUTTER: When testing cubit, loading state isn't emitted, only loaded state isFLUTTER:测试cubit时,不会发出加载状态,只有加载状态
【发布时间】:2021-01-10 23:01:28
【问题描述】:

当我正常运行我的应用程序时,我执行cubit.getWeather('London') 并且weatherLoading 状态发出,然后weatherLoaded 状态正确发出。

但是,当我为 cubit 运行测试以测试 cubit.getWeather('London') 时,weatherLoading 状态并未发出 - 它直接跳转到 weatherLoaded 状态。

为什么会这样?

状态:

@freezed
abstract class WeatherState with _$WeatherState {
  factory WeatherState.weatherInitial() = WeatherInitial;
  factory WeatherState.weatherLoading() = WeatherLoading;
  factory WeatherState.weatherLoaded(Weather weather) = WeatherLoaded;
  factory WeatherState.weatherError(String message) = WeatherError;
}

肘:

class WeatherCubit extends Cubit<WeatherState> {
  final WeatherRepository _weatherRepository;
  static Weather weather;

  WeatherCubit(this._weatherRepository) : super(WeatherState.weatherInitial());

  Future<void> getWeather(String cityName) async {
    emit(WeatherState.weatherLoading());
    try {
      final weather = await _weatherRepository.fetchWeather(cityName);
      emit(WeatherState.weatherLoaded(weather));
    } on NetworkException {
      emit(WeatherState.weatherError("Network error"));
    }
  }
}

我的天气存储库类有'Future&lt;Weather&gt; fetchWeather(String cityname){...}' 方法。

最后,我的测试:

class MockWeatherRepository extends Mock implements WeatherRepository {}

void main() {
  MockWeatherRepository mockWeatherRepository;
  WeatherCubit cubit;

  final weather = Weather(cityName: 'London', temperatureCelsius: 7);

  setUp(() {
    mockWeatherRepository = MockWeatherRepository();
    when(mockWeatherRepository.fetchWeather(any))
        .thenAnswer((_) async => weather);

    cubit = WeatherCubit(mockWeatherRepository);
  });
  test(
    'emits [WeatherLoading, WeatherLoaded] when successful',
    () async {
      cubit.getWeather('London');

      await expectLater(
        cubit,
        emitsInOrder([ //Fails
          WeatherState.weatherLoading(),
          WeatherState.weatherLoaded(weather),
        ]),
      );
    },
  );
}

【问题讨论】:

  • 我遇到了完全相同的问题,并且无法找出为什么 emitsinorder 只跟踪最后一次发射。当我调试时,我可以看到他发出了其他状态。

标签: flutter dart bloc flutter-test


【解决方案1】:

经过一天的停顿,我找到了解决办法。 将 expectLater 放在肘“行为”之前。
正如我从 resoCoder 中读到的,作为一个集团的例子:

通常没有必要在实际调度事件之前调用 expectLater,因为 Stream 发出它的第一个值需要一些时间。不过,为了安全起见,我喜欢犯错。

我猜这不适用于 cubits,你应该总是在调用 cubits 上的方法之前调用 expectLater。

test(
'emits [WeatherLoading, WeatherLoaded] when successful',
  () {
    expectLater(
      cubit,
      emitsInOrder([ //Fails
        WeatherState.weatherLoading(),
        WeatherState.weatherLoaded(weather),
      ]),
    );
    cubit.getWeather('London');
  },
);

替代方法,来自阅读 bloc_test: 您可以使用 blocTest:

blocTest 使用给定的参数创建一个新的特定于 cubit 的测试用例 描述。 blocTest 将处理断言 cubit 发出 执行动作后的预期状态(按顺序)。块测试也 句柄确保不会通过关闭 评估期望之前的肘流。

就我而言,只是将测试移动到 bloctest 就像我预期的测试一样。

  blocTest('emits [WeatherLoading, WeatherLoaded] when successful',
  build: () => WeatherCubit(mockWeatherRepository),
  act: (WeatherCubit cubit) {
    when(mockWeatherRepository.fetchWeather(any)).thenAnswer((_) => weather);
    cubit.getWeather('London');
  },
  expect: [
    WeatherState.weatherLoading(),
    WeatherState.weatherLoaded(weather),
  ]);

【讨论】:

    猜你喜欢
    • 2022-01-21
    • 2021-03-13
    • 2022-12-14
    • 2021-09-03
    • 2015-11-14
    • 2022-12-19
    • 2021-12-14
    • 2018-08-10
    • 1970-01-01
    相关资源
    最近更新 更多