在 JavaScript 中断言非等待异步函数的结果

问题描述 投票:0回答:1

考虑下面的虚假帐户创建代码:

export const accounts = [];
export const emails = [];

export async function createAccount(name, email) {
    accounts.push({name, email});
    void sendEmail(email);
}

async function sendEmail(email) {
    setTimeout(0, () => emails.push(`Account created to ${email}`));
}

createAccount()
函数在数组中“保存”一个帐户,然后“发送电子邮件”报告该帐户已创建。请注意,
createAccount()
不会等待电子邮件发送
,因为这可能需要一些时间。

现在,我们编写一个测试来确保电子邮件已发送:

import {assert} from 'chai';
import {createAccount, emails} from './index.js';

describe('test', async () => {
  it('test', async() => {
    await createAccount('John Doe', '[email protected]');
    assert(emails[0], 'Account created to [email protected]');
  });
});

当然,但是,测试没有通过...

$ npm run test

> [email protected] test
> mocha test.js



  test
    1) test


  0 passing (5ms)
  1 failing

  1) test
       test:
     AssertionError: Account created to [email protected]
      at Context.<anonymous> (file:///home/me/sandbox/foo/test.js:7:5)

...因为异步调用的

sendEmail()
函数尚未“发送”电子邮件。

但我真的很想测试一下邮件最终是否发送成功!

我该如何测试?

理想情况下,不会:

  • 涉及公开
    sendEmail()
    返回值;
  • 涉及睡眠/超时。

有什么想法吗?

附录

为了使测试更容易,您可以使用这个

package.json

{
  "name": "foo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "mocha test.js"
  },
  "type": "module",
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "chai": "^5.1.1",
    "mocha": "^10.6.0"
  }
}
javascript unit-testing asynchronous async-await
1个回答
0
投票
  1. 您可以接受电子邮件发送后触发的回调。
  2. 您可以测试副作用(例如,获取一些东西来拦截对电子邮件 API 的调用)。
  3. 您的 createAccount 可能会返回一个仅在电子邮件发送后才解决的承诺。请注意,返回一个具有
    emailSentPromise
    属性的对象与主要返回的 Promise 分开是可以的。
  4. 您可以使用模拟/依赖注入让调用者提供
    sendEmail
    的实现,而不是默认的实现。
© www.soinside.com 2019 - 2024. All rights reserved.