I can test setTimeout with a normal function like this:
function doAsync() {
setTimeout(doAsync, 1000)
}
jest.useFakeTimers()
test("setTimeout with function", async () => {
doAsync()
jest.advanceTimersByTime(2500)
expect(setTimeout).toBeCalledTimes(3)
})
But when I use it with class method, it cannot refer to this
, Cannot read properties of null (reading 'doAsync')
:
class Test {
doAsync() {
setTimeout(this.doAsync, 1000)
}
}
jest.useFakeTimers()
test("setTimeout with class method", async () => {
new Test().doAsync()
jest.advanceTimersByTime(2500)
expect(setTimeout).toBeCalledTimes(3)
})
How can I test with a class method like this?
CodePudding user response:
You need to write :
class Test {
doAsync() {
setTimeout(() => this.doAsync(), 1000)
}
}
It's because when you write this.doAsync, at the moment of the setTimeout execution, this does exist anymore.
But if round it up around a lambda, the this reference is copied in it at his declaration and so it reference the good instance when it's called later.
Hope it's helps.
CodePudding user response:
Wrap this.doAsync
call into an arrow function to preserve the reference to this
class Test {
doAsync() {
setTimeout(() => this.doAsync(), 1000)
}
}