【问题标题】:Mocha & Chai - Test if async function throws TypeError when passed invalid param?Mocha & Chai - 测试异步函数在传递无效参数时是否抛出 TypeError?
【发布时间】:2020-07-21 03:28:35
【问题描述】:

我有这个功能:

const DEFAULT_ROLES = [
  'Director',
  'Admin',
]; // Default Policy

async function aliasIsAdmin(alias, roles = DEFAULT_ROLES) {
  const url = 'https://foobarapi.execute-api.us-west-2.amazonaws.com/foo/bar/'; 

  //How to test for this throw, for example?
  if (typeof alias !== 'string') {
    throw new TypeError(`Entity "alias" must be a string but got "${typeof alias}" instead.`); 
  }

  if (!Array.isArray(roles)) {
    throw new TypeError(`Entity "roles" must be an array but got "${typeof roles}" instead.`);
  } else if (roles.some((role) => typeof role !== 'string')) {
    throw new TypeError(`Entity "roles" must be an array of strings but got at least one element of type: "${typeof roles}" instead.`);
  }

  const { data } = (await axios.get(url + alias)); // Fetch roles that the alias holds.
  return data.some((role) => roles.includes(role));
}

如何使用 Mocha 和 Chai 测试传递无效参数时函数是否抛出?

例如,async 函数 aliasIsAdmin() 应该抛出 TypeError: Entity "alias" must be a string but got "undefined" instead.,因为该特定调用的 alias 参数是 undefined

如果我这样做:

it('throws TypeError when alias param is not typeof "string"', async () => {
    assert.throws(async function () { await aliasIsAdmin() }, TypeError, /must be string/);
}); 

我明白了:

aliasIsAdmin
    1) throws TypeError when alias param is not typeof "string"
(node:77600) UnhandledPromiseRejectionWarning: TypeError: Entity "alias" must be a string 
but got "undefined" instead.
[... stacktrace continues ...]

  1) aliasIsAdmin
   throws TypeError when alias param is not typeof "string":
 AssertionError: expected [Function] to throw TypeError
  at Context.<anonymous> (test/permissions-manager-client.test.js:25:16)
  at processImmediate (internal/timers.js:439:21)
  at process.topLevelDomainCallback (domain.js:130:23)

我找不到带有 async 函数的示例,所以我想这就是它不起作用的原因。

有解决办法吗?

【问题讨论】:

    标签: javascript asynchronous async-await mocha.js chai


    【解决方案1】:

    尝试将其包裹在 try/catch 中,因为它会抛出 Error

    it('throws TypeError when alias param is not typeof "string"', async () => {
        try {
            await aliasIsAdmin();
        } catch(error) {
            // Do your assertion here
            expect(error).to.be.an('error');
            expect(error.name).to.be.equal('TypeError');
            expect(error.message).to.be.equal('Entity "alias" must be a string but got "undefined" instead.');
        }
    }); 
    

    (或)

    编辑

    it('throws TypeError when alias param is not typeof "string"', async () => {
        await expect(aliasIsAdmin()).to.be.rejectedWith(TypeError);
    }); 
    

    (最后) 如需更完整的解决方案,可以测试一条消息:

    it('throws TypeError when alias param is not typeof "string"', async () => {
        await expect(aliasIsAdmin()).to.be.rejectedWith(TypeError, 'Entity "alias" must be a string but got "undefined" instead.');
    }); 
    

    【讨论】:

    • 您建议如何进行断言? ... catch(error){ expect(error).to.throw(TypeError)} 不起作用,但 expect(error).to.be.an('error') 会。但是,它希望它更冗长一些。如果它测试它是否为TypeError 并确保它发出正确的消息,那又如何呢?不过还是很感谢您的建议,非常感谢!
    • 更新了我的答案。请你试试expect(error.name).to.be.equal('TypeError');。希望对您有所帮助。
    • 有效!我希望 Chai 有一些内置的功能,可以更容易地测试这种情况。我的团队正在从 Jest 转移到 Mocha + Chai,我不喜欢它。在做了一些研究之后,我found some posts 建议从概念上讲,异步函数内部的throwing 是不正确的,我们应该reject。我还注意到有一些 Chai 功能可以处理reject,所以由于提到的反模式,我可能是导致问题的人。非常感谢!
    • 这比我预期的要好得多。我今天在研究时偶然发现了chai-as-promised,但不想使用它,因为它似乎有点过时了。我的意思是看this。我的意思是它说,3 年前发布...这不是有点陈旧吗?但话又说回来,785,089 每周下载量听起来人们相信它。你对此有何看法?无论如何,我会继续寻找一个更开箱即用的解决方案,但你有很大的帮助,现在我认为你的答案是完美的。谢谢。
    • 感谢您的赞赏。 每周下载更多! - 原因可能是,组织/组织中的某些团队正在强力推动人们走向它 ?。因为它很旧,他们对此很满意。除了每周下载,我还会在选择我的库时考虑 github 中的 stars(开发人员喜欢它)。例如:Jest(31k+ 星)vs Mocha(19k+ 星)。
    猜你喜欢
    • 2015-04-04
    • 1970-01-01
    • 1970-01-01
    • 2018-10-02
    • 1970-01-01
    • 2015-06-02
    • 2020-03-16
    • 2018-03-06
    • 2012-09-29
    相关资源
    最近更新 更多