I'm trying to implement my own mocking date function and I want it to works concurently.
I think the optimal usage would be:
mockDate(myFirstDate, async () => {
// Here and only here Date.now() === myFirstDate
})
mockDate(mySecondDate, async () => {
// Here and only here Date.now() === mySecondDate
})
// Outside Date.now is working as expected
Here is a minimal failing code sample for what I'm trying to achieve :
async function mockDate(timestamp, callback) {
const original_now = Date.now
Date.now = function() {
if (/* How can I check Date.now have been called inside callback */ true) return timestamp
else return original_now()
}
await callback()
Date.now = original_now
}
const wait = ms => new Promise(res => setTimeout(res, ms))
mockDate(1600000000000, async () => {
await wait(100)
const result = Date.now()
if (result !== 1600000000000) throw new Error('Fail: 1600000000000')
}).catch(console.error)
mockDate(1650000000000, async () => {
const result = Date.now()
if (result !== 1650000000000) throw new Error('Fail: 1650000000000')
await wait(200)
}).catch(console.error)
My idea is to check inside the if
if I can retrieve callback
inside this.caller
. Unfortunately accessing this.caller
gives me an error.
Also I know tests frameworks usually have serial mode but I'm trying to avoid it.
禁用严格模式或使用串行模式。
This is a working solution:
async function mockDate(timestamp, callback) {
const original_now = Date.now
Date.now = function() {
try {
let caller = arguments.callee.caller
while (caller !== callback && caller.caller) {
caller = caller.caller
}
return caller === callback
? timestamp
: original_now()
} catch {
return original_now()
}
}
await callback()
Date.now = original_now
}
A major drawback to this solution is that you can't use arrow function
mockDate(date, async () => {
const date1 = (function() { return Date.now() })() // Date is mocked
const date2 = (() => Date.now())() // Date wont be mocked
})
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.