【问题标题】:Dart, Flutter Redux Thunk unit testingDart、Flutter Redux Thunk 单元测试
【发布时间】:2020-01-18 10:03:03
【问题描述】:

我已经编写了以下代码,并试图在颤振中测试一个 redux thunk 动作。不幸的是,当我调试代码时,我可以看到 thunkMiddleware 没有按预期拦截操作(因为返回的 Function(store) 永远不会被触发)。

state.dart

@JsonSerialize()
class Pokemon {
  final String name;
  final String url;

  Pokemon(this.name, this.url);

  factory Pokemon.fromJson(Map<String, dynamic> json) =>
      _$PokemonFromJson(json);
}

// state
@immutable
class PokemonsState {
  final List<Pokemon> pokemons;
  final bool isLoading;
  final Exception ex;

  const PokemonsState(
      {this.pokemons = const [], this.isLoading = false, this.ex});

  PokemonsState copyWith(
      {List<Pokemon> pokemons, bool isLoading, Exception ex}) {
    return PokemonsState(
        pokemons: pokemons ?? this.pokemons,
        isLoading: isLoading ?? this.isLoading,
        ex: ex ?? this.ex);
  }
}

// reducer
PokemonsState pokemonsState(PokemonsState state, action) {
  switch (action.runtimeType) {
    case FetchPokemons:
      return state.copyWith(isLoading: true);
    case AddPokemons:
      if (action.error == null)
        return state.copyWith(
            pokemons: action.payload, isLoading: false, ex: null);

      return state.copyWith(ex: action.error, isLoading: false);
  }
  return state;
}

// actions
class FetchPokemons {}

class AddPokemons {
  final List<Pokemon> payload;
  final Exception error;

  AddPokemons({this.payload, this.error});
}

// thunks
loadPokemons(Client client) {
  return (Store<AppState> store) async {
    store.dispatch(FetchPokemons());
    try {
      var res = await client.get(pokemonUrl);
      if (res.statusCode == HttpStatus.ok) {
        final pokemons = jsonDecode(res.body)['results'];
        store.dispatch(AddPokemons(
            payload:
                List<Pokemon>.from(pokemons.map((i) => Pokemon.fromJson(i)))));
      } else {
        throw HttpException(res.reasonPhrase);
      }
    } on Exception catch (e) {
      store.dispatch(AddPokemons(error: e));
    }
  };
}


state_test.dart

class MockClient extends Mock implements Client{}

void main(){

    Store<PokemonsState> store;

    setUp(() {
      store = Store(pokemonsState,
          initialState: PokemonsState(), middleware: [thunkMiddleware]);
    });

    test('add Pokemons success should add a list of pokemons to the store',
            () {
          final client = MockClient();

          when(client.get(argThat(isInstanceOf<String>()))).thenAnswer((_) async =>
              Response(
                  '{"results": [{"name": "p1", "url": "u1"}, {"name": "p2", "url": "u2"}]}',
                  200));

          store.dispatch(loadPokemons(client));
          expect(store.state.pokemons.length, 2);
        });
      });

}

我们将不胜感激任何修复测试的帮助!

【问题讨论】:

    标签: flutter dart redux-thunk flutter-test flutter-redux


    【解决方案1】:

    我遇到了同样的问题。这是我的解决方案:

    void main() {
      Store<AppState> store;
    
      setUp(() {
        store = Store(
          appStateReducer,
          initialState: AppState.initialState(),
          middleware: [thunkMiddleware],
        );
      });
    
      test('', () async {
        await store.dispatch(fetchLocalization());
        expect(store.state.localization.get('WELCOME'), 'Welcome');
      });
    }
    

    我确实创建了一个自定义 appStateReducer,但它绑定到不进行任何 http 调用的操作。

    这里是:

    class SetLocalization {
      final Map<String, String> values;
      SetLocalization(this.values);
    }
    
    ThunkAction<AppState> fetchLocalization() {
      return (Store<AppState> store) async {
        var localization = await _LocalizationApi().read();
        store.dispatch(SetLocalization(localization));
      };
    }
    
    // used to fake http call
    class _LocalizationApi {
      final Map<String, String> data = {
        'WELCOME': 'WECLOME',
        'WELCOME_MESSAGE': 'Welcome'
      };
      Future<Map<String, String>> read() async => data;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-18
      • 2017-07-29
      • 2021-09-13
      • 2019-01-08
      • 1970-01-01
      • 2017-03-03
      • 2018-09-27
      相关资源
      最近更新 更多