【发布时间】:2021-09-15 23:28:52
【问题描述】:
我目前在useEffect 中有一个setTimeOut,我可以使用以下方法对其进行测试:
jest.useFakeTimers();
jest.advanceTimersByTime(5000);
而且效果很好。但是,随着successMessage 的变化,setTimeout 会被触发几次。如何编写一个测试来检查 setTimeOut 仅在 successMessage 不是空字符串时被调用?
我正在使用 jest 和 react-testing-library。
这是我的反应代码。
enum HELPER_MESSAGES {
SUCCESS = 'Congratulations you signed up!',
ERROR = 'Email address invalid',
}
export function EmailCapture (): ReactElement {
const [inputValue, setInputValue] = useState<string>('');
const [errorMessage, setErrorMessage] = useState<string>('');
const [successMessage, setSuccessMessage] = useState<string>('');
function handleOnClick (): void {
const EMAIL_REGEX: RegExp = /^[a-zA-Z0-9]+([-._][a-zA-Z0-9]+)*@([a-zA-Z0-9]+(-[a-zA-Z0-9]+)*.)+\.+[a-zA-Z]{2,}$/;
const isInputValid: boolean = EMAIL_REGEX.test(inputValue) && inputValue !== '';
if (isInputValid) {
setSuccessMessage(HELPER_MESSAGES.SUCCESS);
} else {
setErrorMessage(HELPER_MESSAGES.ERROR);
}
}
useEffect((): () => void => {
const resetAfterSuccessTimer: NodeJS.Timeout = setTimeout((): void => {
setSuccessMessage('');
}, 5000);
return (): void => {
clearTimeout(resetAfterSuccessTimer);
};
}, [successMessage]);
function handleOnChange (e: ChangeEvent<HTMLInputElement>): void {
setInputValue(e.target.value);
setErrorMessage('');
setSuccessMessage('');
}
return (
<TextInput
onChange={handleOnChange}
error={errorMessage}
success={successMessage}
value={inputValue}
/>
);
}
我正在关注 TDD,所以我希望编写一个测试,让我编写以下代码:
useEffect((): () => void => {
let resetAfterSuccessTimer: NodeJS.Timeout;
if (successMessage) {
resetAfterSuccessTimer= setTimeout((): void => {
setSuccessMessage('');
setButtonText('Sign up!');
console.log('sexy');
}, 5000);
}
return (): void => {
clearTimeout(resetAfterSuccessTimer);
};
}, [successMessage]);
sexy 这个词应该只会让控制台记录一次。
【问题讨论】:
-
实例化后,不应该被调用。在successMessage之后它应该被调用一次,因为它改变了successMessage它调用useEffect但它不调用setTimeout......我相信就是这样......
-
@Noriller 我不确定我是否理解
标签: reactjs jestjs settimeout use-effect react-testing-library