开玩笑是否运行用于测试“ toThrowError”的包装函数?

时间:2019-01-10 12:11:52

标签: node.js unit-testing testing jestjs

我在使用jest toThrowError函数时遇到麻烦。

我有一个函数,该函数使用redis设置调用该函数的限制,即,每次使用某个键调用此函数时,它都会调用redis.incr(key),并且如果该数字大于指定的限制,该函数抛出throw LIMITED错误,否则该函数将不返回任何内容。

为简单起见,我们可以这样定义此功能:

async function fn(key) {
    const count = await redis.incr(key)
    if(count > limit)
        throw new Error('LIMITED')
    // do other stuff.
}

现在,我想测试fn的此功能,因此,如果limit=2我两次调用fn,并且再次调用它必须抛出LIMITED错误。

这是我的考试:

it('should throw LIMITED error', async () => {
    const key = 'somekey'
    await fn(key)
    await fn(key)
    expect(async () => { await fn(key) }).toThrowError('LIMITED')
}

但是当我运行测试时,它说:

Expected the function to throw an error matching:
  "LIMITED"
But it didn't throw anything.

这很奇怪,因为当我将测试代码更改为以下内容时:

it('should throw LIMITED error', async () => {
    const key = 'somekey'
    await fn(key)
    await fn(key)
    await fn(key)
}

然后它在运行测试期间抛出LIMITED错误,并失败。

我不确定我在尝试测试功能行为时是否完全理解预期功能的工作原理,因此,如果有更好的方法进行这种测试,我将不胜感激。

更新:

我以为我可以在Expect使用的包装函数中调用fn三次,如下所示:

it('should throw LIMITED error', async () => {
    const key = '
    expect(async () => { 
        await fn(key)
        await fn(key)
        await fn(key)
    }).toThrowError('LIMITED')
}

但是即使这样也不会引发LIMITED错误。

我什至在console.log内添加了fn来查看它是否被调用,但是当我将fn放在expect的包装函数中时,它不打印任何内容。 / p>

所以我现在很想知道在尝试测试功能时期望如何工作。

1 个答案:

答案 0 :(得分:1)

toThrowError断言运行try..catch提供的功能,这是捕获导致异常的代码中错误的唯一方法。

应该使用rejects而不是toThrowError声明被拒绝的诺言,因为async函数从不实际抛出错误。它是诺言的语法糖,如果抛出错误,它会返回被拒绝的诺言。在throw new Error(...)中使用时,return Promise.reject(new Error(...))async相对。

async () => { 
    await fn(key)
    await fn(key)
    await fn(key)
}

不能被认为是测试的好函数,因为它很松散,并且不能精确地测试哪个调用会导致错误。

可能应该是:

...
await fn(key)
await fn(key)
await expect(fn(key)).rejects.toMatch('LIMITED')