如何模拟React setState进行API测试

时间:2019-11-02 16:19:08

标签: reactjs unit-testing testing jestjs react-hooks

我已经构建了一个我想测试的react组件api。出于测试目的,该api独立于react useState挂钩。这样,我的api从我创建的自定义钩子useAPI中获得了状态和setState:

const useAPI = (api, initialState) => {
    const [state, setState] = useState(initialState)
    return api({ state, setState })
}

以及我的api的简化示例:

const anAPI = ({state, setState}) => {
    const name = state.name
    const surname = state.surname

    const updateName = (newValue) => {
        setState(prevState => (
            {...prevState, name: newValue}
        )) 
    }
}

我想在不使用任何钩子的情况下测试此api。但是,我不确定如何模拟setState函数,以便可以将其传递到api中并使其正常工作。简化的测试文件可能如下所示:

const state = {name: "", surname: ""}

const setState = someFunction...

const api = anAPI({state, setState})

it("updates name", () => {
    api.updateName("john")
    expect(api.name).toEqual("john")
})

setState需要什么样的外观才能使该测试正常工作?

1 个答案:

答案 0 :(得分:0)

想通了:

const useApiMock = (api, defaultValue) => {
    let state = defaultValue;
    let setState = updater => {
      if (typeof updater === "function") {
        state = updater(state);
      } else {
        state = updater;
      }
      ref.api = api({ state, setState });
    };
    let ref = {
      api: api({ state, setState })
    };
    return ref;
  };

然后这样使用:

const mockApi = useApiMock(someApi, someState)

it("updates name", () => {
    mockApi.api.updateName("new name")
    expect(mockApi.api.name).toEqual("new name")
})