MrWolfZ/ngrx-forms

Testing create reducer

pinkman84 opened this issue · 4 comments

Hi,
trying to set up some unit tests (Jasmine), this is the first reducer we have that uses the createReducer with createActions, when trying to set up a simple test the initial state of the form seem to need some values to be defined.

import { initialState, reducer } from './thing.reducer';

describe('reducer', () => {
  it('should return default state on unknown action', () => {
    const action = { type: 'unknown' } as any;
    const result = reducer(undefined, action);

    expect(result).toEqual(initialState)
  });
});

but I get an error that looks like

        Expected $.form.errors not to have properties
            _name: Object({ required: Object({ actual: '' }), minLength: Object({ minLength: 1, value: '', actualLength: 0 }) })
            _thingArray: Object({ required: Object({ actual: [  ] }), minLength: Object({ minLength: 1, value: [  ], actualLength: 0 }) })
        Expected $.form.isValid = false to equal true.
        Expected $.form.isInvalid = true to equal false.
        Expected $.form.controls.name.errors not to have properties
            required: Object({ actual: '' })
            minLength: Object({ minLength: 1, value: '', actualLength: 0 })
        Expected $.form.controls.name.isValid = false to equal true.
        Expected $.form.controls.name.isInvalid = true to equal false.
        Expected $.form.controls.thingArray.errors not to have properties
            required: Object({ actual: [  ] })
            minLength: Object({ minLength: 1, value: [  ], actualLength: 0 })
        Expected $.form.controls.thingArray.isValid = false to equal true.
        Expected $.form.controls.thingArray.isInvalid = true to equal false.

I can't set values directly onto the form because the values are readonly.

Can't tell from information you provided. Show your reducer.

sorry, here it is, I added the form too

export const initialState: State = {
  form: formImport.InitialFormState
};

const rawReducer = createReducer(
  initialState,
  onNgrxForms(),
  on(updateForm, (state: State, props: Something) => ({
    ...state,
    form: validateAndUpdateForm(setValue(state.form, props))
  }))
);

const wrappedReducer = wrapReducerWithFormStateUpdate(
  rawReducer,
  (state: State) => state.modifierGroupForm,
  validateAndUpdateForm
);

export function reducer(state: State, action: Action): State {
  return wrappedReducer(state, action);
}
export const FORM_ID = 'form.FormGroup';

export const InitialFormState = createFormGroupState<Something>(FORM_ID, {
  date: null,
  id: null,
  name: string
  arrayOfObjects: [],
});

export const validateAndUpdateForm = updateGroup<StepModel>({
  name: validate(required),
  arrayOfObjects: validate(required, minLength(1))
});

This is expected because your initialState goes through entire reducer including your validateAndUpdateForm which runs all the validations on empty form.

I don't see any big issue to update the matcher:

expect(result).toEqual(validateAndUpdateForm(initialState));

ah I was struggling to make that link. Thank you for the help - I managed to get it working a slightly different way but this syntax is much nicer. Thanks