Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Testing with Dart Redux Thunks #15

Open
aprofromindia opened this issue Sep 24, 2019 · 1 comment
Open

Testing with Dart Redux Thunks #15

aprofromindia opened this issue Sep 24, 2019 · 1 comment

Comments

@aprofromindia
Copy link

I have written the following code and am trying to test a redux thunk action in flutter. Unfortunately when I debug the code, I can see the thunkMiddleware doesn't intercept the action as expected (as the returned Function(store) never gets triggered).

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);
        });
      });

}

Any help in fixing the test would be most appreciated!

@aprofromindia aprofromindia changed the title Testing Dart Redux Thunks Testing with Dart Redux Thunks Sep 24, 2019
@AndiDog
Copy link

AndiDog commented Jan 27, 2021

Thunk actions are asynchronous and therefore you won't immediately see the expected result in the state, but with a small delay. You might try a CallableThunkAction and then await MyCallableThunkAction().call(store) instead of store.dispatch(...), but I haven't tried that. In case the thunk action dispatches more asynchronous actions, and you need to wait for them to be finished, that suggestion will surely not work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants