У меня есть действие в моем componentDidMount, которое извлекает изображения из Reddit через 30000 мс. Я хочу проверить это, но не могу понять?!?! Какие-либо предложения?
componentDidMount() {
this.getHumorEvery(30000)
}
getHumorEvery = async (ms) => {
await this.props.getHumor()
return setInterval(() => {
this.props.getHumor()
}, ms)
Так что getHumor () получает вызов немедленно. Затем через 30000 мс он снова вызывается и так далее.
Тогда мой тест ...
it('should refetch images every 30000 ms', () => {
const clock = sinon.useFakeTimers();
const getHumorSpy = sinon.spy();
renderComponent(requiredProps({ getHumor: getHumorSpy }));
clock.tick(30000)
sinon.assert.calledTwice(getHumorSpy)
})
Тест не пройден, потому что getHumor вызывается только один раз. SetInterval () никогда не запускается?
Да, если вы console.info (setInterval) прямо перед вызовом setInterval, а затем поместите другой console.info () в setTimeout, а затем запустите тесты, результат будет .... 1) setInterval выводит заглушенный setInterval 2) console.info () внутри setInterval никогда не выходит из системы Таким образом, кажется, что да, setInterval заглушен правильно, но все же он никогда не вызывает setInerval ()
Пробовали ставить галочку на что-то выше, например 40000?
Я сделал .. Я пробовал несколько раз.
Зачем нужен async/await в getHumorEvery()? Думаю, причина в этом.





Вызов затем на обещаниях и вызов await в асинхронной функции ставит в очередь код для цикла событий, который не выполняется до тех пор, пока не завершится текущий синхронный код и не отсчитываются часы. Точно так же setTimeout обычно добавляет код в очередь, который также должен ждать следующего такта часов.
Поддельные таймеры Sinon «являются синхронными реализациями setTimeout и друзей», которые «перезаписывают глобальные функции» и управляют кодом, поставленным в очередь с setTimeout и подобными глобальными переменными, и вызывают его синхронно, когда тикают смоделированные часы.
Это разъединение между кодом, который все еще находится в очереди для цикла событий, и кодом, который ранее был поставлен в очередь для цикла событий, но теперь вызывается синхронно, может вызвать проблемы (например, это и это).
Эти проблемы часто можно решить, вставив ручной цикл цикла событий, чтобы разрешить выполнение любого ожидающего кода в очереди перед синхронной имитацией тика часов.
В этом случае превращение теста в асинхронную функцию и вызов await для разрешенного обещания дает ожидающему коду в очереди возможность запускаться до синхронного тика часов, что позволяет коду вести себя так, как ожидалось, и правильно утверждать:
it('should refetch images every 30000 ms', async () => {
const clock = sinon.useFakeTimers();
const getHumorSpy = sinon.spy();
renderComponent(requiredProps({ getHumor: getHumorSpy }));
// let event loop cycle
await Promise.resolve();
clock.tick(30000);
sinon.assert.calledTwice(getHumorSpy);
})
Я бы попытался заменить clock.tick на clock.tickAsync и избежать лишнего await Promise.resolve();
Вызывается ли когда-либо ваш обратный вызов setInterval? Если да, то определен ли
this.props.getHumorвнутри обратного вызова, и уверены ли вы, что это шпион sinon?