我已经编写了以下代码,并试图在颤振中测试一个 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);
});
});
}
任何修复测试的帮助将不胜感激!