0

我正在编写一个测试来检查更新 TextInput 并模糊它是否会在更改发送到我的 Rails 服务器后保存对我的人状态的更改。

这目前 100% 在生产中工作,但试图围绕这个编写测试让我发疯。似乎dispatch()启动我的操作的 redux 函数永远不会返回和/或完成,并且测试在我看到商店更改之前完成。

我已经搜索了整个谷歌并且没有看到其他人真正抱怨这个所以IDK如果代码设置或测试有问题。

测试

const fillIn = (field, value) => {
  fireEvent.changeText(field, value);
  fireEvent(field, 'blur');
}

const setUpState = async (store, personExtras={}) => {
  await act(async () => {
    await store.dispatch(PersonActions.set({...groucho, ...personExtras}));
  })

  await waitFor(() => expect(store.getState().person.person).not.toBeNull())
}

const stubUpdatePersonWith = (data) => {
  // creates on fly stub/return value for api request
  appendServer({
    url: '/people/:personID',
    method: 'put',
    result: {...groucho, ...data}
  })
}

describe('PersonEditScreen', () => {
  // using msw to prevent actual API requests
  beforeAll(() => server.listen())
  afterEach(() => server.resetHandlers())
  afterAll(() => server.close())

  test('can change first_name', async () => {
    stubUpdatePersonWith({first_name: 'Zeppo'});
    const { getByText, getByTestId, store } = setup();
    await setUpState(store);

    await waitFor(() => expect(getByTestId('string-first_name')).toBeTruthy());
    fillIn(getByTestId('string-first_name'), 'Zeppo')

    await waitFor(() => expect(store.getState().person.person.first_name).toEqual('Zeppo'));
  })
}

屏幕/视图

function PersonEditForm({person}){
  const { updatePerson } = usePersonStore();

  const onSave = useCallback(async (field, value) => {
    console.log("onSave?!"); // <~ logs ok
    updatePerson({[field]: value})
    console.log("onSave finished"); <~ never logs
  }, [updatePerson]);

  return(<View>...</View>);
}

usePersonStore 钩子

export default function usePersonStore(){
  const dispatch = useDispatch();

  return useMemo(() => ({
    async updatePerson(data){
      console.log("updatePerson dispatch start"); // <~ logs ok
      const { payload } = await dispatch(PersonActions.update(data));
      console.log("updatePerson dispatch done!"); <~ never logs

      return payload.error
        ? { changes: data, failed: payload.error }
        : { changes: data, updated: data };
    },
  })
}

PersonAction (redux)

export const PersonActions = {
  update: createAsyncThunk('PERSON.UPDATE', async (data, {getState}) => {
    const id = PersonSelectors.selectID(getState());
    console.log('PersonActions.update start') // <~ logs ok
    const { result } = await PersonAPI.update(id, data);
    console.log('PersonActions.update api finished') // <~ logs ok

    return { person: result, error };
  }),
}

运行测试时,我发现它永远不会更新,并且console.log永远dispatch(PersonAction.updatePerson)不会打印出来。

● PersonEditScreen › can change first_name

    expect(received).toEqual(expected) // deep equality

    Expected: "Zeppo"
    Received: "Groucho"

      134 |     
    > 135 |     await waitFor(() => expect(store.getState().person.person.first_name).toEqual('Zeppo'));
          |           ^
      136 |   })
      137 | })
4

0 回答 0