angularjasminekarma-runnerngrx-reducers

Unit testing. Reducer does not change state after dispatching action


I am trying to perform simple reducer test. new StartLoading(); is dispatched this should set isLoading to true. Unfortunately it shows: Expected $.isLoading = false to equal true.

Nothing fancy. This is how test looks like:

   it('should set isLoading to true', () => {
        const isLoading = true;

        const action = new StartLoading();
        const newState = uiReducers(initialState, action);

        const expectedState = { ...initialState, isLoading };

        expect(newState).toEqual(expectedState);
    })

And reducer:

export interface UIState {
    isLoading: boolean;
}

export const initialState: UIState = {
    isLoading: false
};

export function uiReducers(state = initialState, action: UIActions) {
    switch (action.type) {
        case UIActionTypes.START_LOADING: {
            console.log('stt')
            return {
                isLoading: true,
                ...state
            };
        }
        case UIActionTypes.STOP_LOADING: {
            return {
                isLoading: false,
                ...state
            };
        }
        default:
            return {
                ...state
            }
    }

}

Solution

  • I believe the problem you’re facing is due to the order of the elements on the object spread operator.

    Your initialState has isLoading = false and you are setting it in the right side of the object assignment (by putting ...state as the second part of the operator). Meaning, it will always override the isLoading that you are trying to set. You should try something like

    case UIActionTypes.START_LOADING: {
                console.log('stt')
                return {
                    ...state
                    isLoading: true,
                };
            }
    

    This way you are telling the operator to use the state as the origin object and to change the isLoading property with the new value.

    If you check this example in the documentation you will see that the state is defined in the left side and then the new properties on the right side (or in the bottom in case they are in multiple lines)