我正在学习React,现在正在尝试单元测试。我具有以下代码片段的登录功能组件:
const [users, setUsers] = useState<User[]>([]);
useEffect(() => {
usersService.getUsers().then((allUsers: User[]) => {
setUsers(allUsers);
});
}, []); // eslint-disable-line react-hooks/exhaustive-deps
当我运行该应用程序时,一切正常。但是,当我尝试为此运行测试时,它不会将用户设置为state。这是我编写的模拟和测试:
const usersServiceMock: UsersService = {
getUsers: (): Promise<User[]> => {
return new Promise((resolve) => {
process.nextTick(() =>
resolve([{ username: 'test', password: 'test', imageUrl: '', id: 0 } as User])
);
});
},
} as UsersService;
it('logs user in', async () => {
const loginSpy = jest.spyOn(loginServiceMock, 'logUserIn');
const usersSpy = jest.spyOn(usersServiceMock, 'getUsers');
const component = render(
<Login loginService={loginServiceMock} usersService={usersServiceMock} />
);
expect(usersSpy).toHaveBeenCalledTimes(1);
//up until here, test is fine, but users are not set inside component
});
可以正确提供模拟服务,并且可以正确解析模拟的用户数据,但是setUsers(allUsers)实际上并未通过测试进行设置。在效果内部,usersService.getUsers()确实获取了模拟数据,但从未设置。
const [users, setUsers] = useState<User[]>([]);
useEffect(() => {
usersService.getUsers().then((allUsers: User[]) => {
// allUsers value is [{ username: 'test', password: 'test', imageUrl: '', id: 0}]
setUsers(allUsers);
// users value is []
});
}, []); // eslint-disable-line react-hooks/exhaustive-deps
这里是使用状态的函数。在运行应用程序时它可以工作,但是在运行测试时,用户仍然是空数组。
const login = (): void => {
const userFromDb = users.find((u) => u.username === user.username);
if (!userFromDb || userFromDb.password !== user.password) {
setUser({
username: '',
password: '',
imageUrl: '',
});
setIsDialogOpen(true);
} else {
loginService.logUserIn(userFromDb);
history.push('/home');
}
};
有任何同伴吗?
答案 0 :(得分:0)
setState
不会更改局部变量(这在js中是不可能的,尤其是在使用const时)。
它只是确保在下一个渲染器中调用useState将返回新值。