当我想测试使用 Redux 的 React 应用程序时,我收到这样的错误,我想测试 thunk 函数寄存器 AssertionError:期望使用参数调用“spy”:[[Function]]
// action.js
function asyncRegisterUser({ name, email, password }) {
return async (dispatch) => {
dispatch(showLoading());
try {
await api.register({ name, email, password });
} catch (error) {
alert(error.message);
}
dispatch(hideLoading());
};
}
export {
asyncRegisterUser,
};
// action.test.js
import { hideLoading, showLoading } from 'react-redux-loading-bar';
import {
afterEach, beforeEach, describe, expect, it, vi,
} from 'vitest';
import api from '../../utils/api';
import { asyncRegisterUser } from './action';
const fakeRegisterResponse = {
id: 'john_doe',
name: 'John Doe',
email: '[email protected]',
avatar: 'https://generated-image-url.jpg',
};
const fakeRegisterInput = {
name: 'John Doe',
email: '[email protected]',
password: 'JohnDoe',
};
const fakeErrorResponse = new Error('Ups, something went wrong');
describe('asyncRegisterUser thunk', () => {
beforeEach(() => {
api._registerUser = api.register;
});
afterEach(() => {
api.register = api._registerUser;
delete api._registerUser;
});
it('should dispatch action correctly when register success', async () => {
api.register = () => Promise.resolve(fakeRegisterResponse);
const dispatch = vi.fn();
await asyncRegisterUser(fakeRegisterInput)(dispatch);
expect(dispatch).toHaveBeenCalledWith(showLoading());
expect(dispatch).toHaveBeenCalledWith(
asyncRegisterUser(fakeRegisterInput), //ERROR HERE
);
expect(dispatch).toHaveBeenCalledWith(hideLoading());
});
it('should dispatch action and call alert correctly when register failed', async () => {
api.register = () => Promise.reject(fakeErrorResponse);
const dispatch = vi.fn();
window.alert = vi.fn();
await asyncRegisterUser(fakeRegisterInput)(dispatch);
expect(dispatch).toHaveBeenCalledWith(showLoading());
expect(dispatch).toHaveBeenCalledWith(hideLoading());
expect(window.alert).toHaveBeenCalledWith(fakeErrorResponse.message);
});
});
当我调用注册函数时,我想在react redux thunk函数上使用vitest进行测试,注册成功时应该正确分派操作
在您的
asyncRegisterUser
动作创建器中,dispatch
函数仅被调用两次,一次使用 showLoading()
,第二次使用 hideLoading()
。
function asyncRegisterUser({ name, email, password }) {
return async (dispatch) => {
dispatch(showLoading()); // <-- dispatch call #1
try {
await api.register({ name, email, password });
} catch (error) {
alert(error.message);
}
dispatch(hideLoading()); // <-- dispatch call #2
};
}
对于您的
asyncRegisterUser
操作触发调用自身可能会非常糟糕,因此可能想断言这 不会 发生。
it('should dispatch action correctly when register success', async () => {
api.register = () => Promise.resolve(fakeRegisterResponse);
const dispatch = vi.fn();
await asyncRegisterUser(fakeRegisterInput)(dispatch);
expect(dispatch).toHaveBeenCalledWith(showLoading()); // <-- dispatch #1
// assert asyncRegisterUser action isn't recursively called
expect(dispatch).not.toHaveBeenCalledWith(
asyncRegisterUser(fakeRegisterInput),
);
expect(dispatch).toHaveBeenCalledWith(hideLoading()); // <-- dispatch #2
});
否则,请删除中间断言,因为
dispatch
显然 不会调用 asyncRegisterUser
。
it('should dispatch action correctly when register success', async () => {
api.register = () => Promise.resolve(fakeRegisterResponse);
const dispatch = vi.fn();
await asyncRegisterUser(fakeRegisterInput)(dispatch);
expect(dispatch).toHaveBeenCalledWith(showLoading()); // <-- dispatch #1
expect(dispatch).toHaveBeenCalledWith(hideLoading()); // <-- dispatch #2
});