我正在编写一个测试来检查更新 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 | })