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

Mock Store State is not being updated after an action has been dispatched #45

Closed
michael-iglesias opened this issue Jun 9, 2016 · 9 comments

Comments

@michael-iglesias
Copy link

michael-iglesias commented Jun 9, 2016

Hello,

For some reason the state within my mocked store is not being updated after an action has been dispatched. I've pasted my unit test below. Any suggestion on how to proceed would be greatly appreciated.

describe('Landing Page Action Creators', () => {
    let store = mockStore({app: {kbbToken: 'MTI2MDk2NjUy'}, ymmt: YMMT_INITIAL_STATE});

    beforeEach(() => {
        // Redux Mock store - clear actions before each test to assert the new actions being dispatched
        store.clearActions();
    });


    describe('Years', () => {
        // getYears()
        it('getYears() -> Should return an array of years dating back to 1992', (done) => {

            const expectedActions = [
                {type: 'GET_YEARS_PENDING'},
                {type: 'GET_YEARS_FULFILLED', payload: LandingMockedResponses.getYears}
            ];

            return store.dispatch(LandingActions.fetchYears())
                .then(() => { // return of async actions
                    done();
                    expect(store.getActions()).to.eql(expectedActions)
                })
        });
        // ***END getYears()

        // setYear(2016)
        it('setYear(year) -> Set selected year (ymmt)', (done) => {
            let expectedActions = [
                {type: 'SET_YEAR', payload: 2016},
                { type: 'GET_MAKES_PENDING' }
            ];
            store.dispatch(LandingActions.setYear(2016));
            done();

            expect(store.getActions()).to.eql(expectedActions);
        });
        // ***END setYear(2016)
    });

    describe('Makes', () => {
        // getMakes()
        it('getMakes() -> Should return an array of makes based on the year passed in', (done) => {
            store.clearActions();

            console.log(store.getState().ymmt);

            let expectedActions = [
                {type: 'GET_MAKES_PENDING'},
                {type: 'GET_MAKES_FULFILLED', payload: LandingMockedResponses.getMakes}
            ];

            return store.dispatch(LandingActions.fetchMakes(2016))
                .then(() => { // return of async actions
                    done();
                    expect(store.getActions()).to.eql(expectedActions)
                })
        });
        // ***END getMakes()
    });



});
@ericat
Copy link

ericat commented Jun 19, 2016

the same thing happens to me, am I doing anything obviously wrong? Trying to follow the example for testing api requests described here under "Async Action Creators"

const middlewares = [ thunk ]
const mockStore = configureMockStore(middlewares)

describe('Todos actions', () => {
  afterEach(() => {
    nock.cleanAll();
  });

  it('creates LOAD_TODOS', () => {
    nock('http://localhost:8080')
      .get('/v1/todos')
      .reply(200, { body: { todos: ['read book'] }})

    const expectedActions = [{
      type: types.LOAD_TODOS,
      body: { todos: ['read book'] },
    }];
    const store = mockStore({ todos: [] })

    return store.dispatch(actions.loadTodos())
      .then(() => {
        console.log(store.getActions()); // { todos: [] }, does not update
        expect(store.getActions()[0]).toEqual(expectedActions)
      })
  });
});

And the action is like this:

export function loadTodos() {
  return (dispatch, getState) => {
    const url = '/v1/todos';

    fetch(url, {
      credentials: 'same-origin'
    })
    .then(checkStatus)
    .then(res => res.json())
    .then(todos =>
      dispatch({
        type: 'LOAD_TODOS',
        payload: todos
      })
    ).catch(err =>
      dispatch({
        type: 'LOAD_ERROR',
        error: `${err} : Request failed`
      })
    );
  }
}

Any help would be appreciated!

@arnaudbenard
Copy link
Contributor

@michael-iglesias @ericat Could you both provide a repo with the minimum working example or a JS fiddle? It would help me to debug the issue

@ericat
Copy link

ericat commented Jun 19, 2016

@arnaudbenard yes and thanks for the quick reply, I will do it asap, probably in the next few days if that's ok with you.

@arnaudbenard
Copy link
Contributor

@ericat No problem! The source of your problem might be that your action loadTodos doesn't return anything. Have you tried this:

export function loadTodos() {
  return (dispatch, getState) => {
    const url = '/v1/todos';

    return fetch(url, {
      credentials: 'same-origin'
    })

...

@adamyonk
Copy link

adamyonk commented Sep 8, 2016

I'm having this same issue. Maybe I'm not understanding this correctly, but does mock-store actually run the actions through the reducer anywhere? I'm not seeing how they're ever connected with a setup like this:

import configureStore from 'redux-mock-store'
import thunk from 'redux-thunk'
const mockStore = configureStore([thunk])
const store = mockStore({ ...state })
console.log(store.getState()) // => { ...state }
store.dispatch(someAction())
console.log(store.getActions()) // => [ someAction() ] The action does show up here!
console.log(store.getState()) // => { ...state } But this is the same unchanged state as above

@damianobarbati
Copy link

I don't get this: why I can't see the updated state here https://github.com/damianobarbati/react-redux-test/blob/master/test.js#L49 if I add let finalState = store.getState();?
Store is always an empty object.

@mustafa-hanif
Copy link

@adamyonk you need to use your reducer like this
store.replaceReducer(rootReducer);

@jose920405
Copy link

@adamyonk you need to use your reducer like this
store.replaceReducer(rootReducer);

Can you explain it better?

@NLSVTN
Copy link

NLSVTN commented Sep 10, 2022

Was the issue solved? I am having the same issue. Tried 1.5.3 and 1.5.4 versions.

  const callback = (store) => (action) => {
    console.log(action)
    store.dispatch(action)
  }

fetchRelatedFamilies()(callback(store), () => currstate)

export const fetchRelatedFamilies = () => {
  return (dispatch, getState) => {
    if (isEmpty(getState().relatedFamiliesById)) {
      dispatch({ type: REQUEST_RELATED_FAMILIES_BY_ID })
      new HttpRequestHelper('/api/related_families',
        (responseJson) => {
          dispatch({ type: RECEIVE_RELATED_FAMILIES_BY_ID, updates: responseJson.relatedFamiliesById })
        },
        e => dispatch({ type: RECEIVE_RELATED_FAMILIES_BY_ID, error: e.message, updates: {} }),
      ).get()
    }
  }
}

OR:

store.dispatch(fetchRelatedFamilies())
expect(store.getActions()).toEqual(expectedActions)

I always see only the first action in store.getActions() but not the second. In both cases 2nd action is dispatched which I see by simply printing it out with console.log().

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

8 participants