颤抖:测试肘部时,不会发出加载状态,只有加载状态

时间:2020-09-24 15:54:17

标签: flutter dart bloc flutter-test

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

但是,当我对肘部进行测试以测试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;
}

Cubit:

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<Weather> 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),
        ]),
      );
    },
  );
}

1 个答案:

答案 0 :(得分:1)

停顿一天后,我找到了解决方案。 将ExpectLater放在肘部“ act”之前。
正如我从resoCoder中读取的一个整体示例:

通常不必在实际调度事件之前调用ExpectLater,因为Stream发出其第一个值需要花费一些时间。不过,我还是想在安全方面犯错误。

我想这对于肘节不是正确的,您应该始终在调用肘节上的方法之前调用ExpectLater。

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

另一种方法,从读取bloc_test: 您可以使用blocTest:

blocTest使用给定的新的特定肘部测试用例 描述。 blocTest将处理断言肘部发出 执行动作后的预期状态(按顺序)。也blocTest 通过关闭 在评估期望值之前先进行肘流。

就我而言,只是将测试移至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),
  ]);