Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/40.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 使用异步初始化代码进行Mocha测试_Node.js_Unit Testing_Typescript_Mocha.js - Fatal编程技术网

Node.js 使用异步初始化代码进行Mocha测试

Node.js 使用异步初始化代码进行Mocha测试,node.js,unit-testing,typescript,mocha.js,Node.js,Unit Testing,Typescript,Mocha.js,我正在为REST客户机库编写测试,该库必须使用OAuth exchange“登录”服务。为了防止我要测试的每个端点都登录,我想写一些“测试设置”,但我不确定该怎么做 我的测试项目结构: 试验 端点类别1.spec.ts 端点类别2.spec.ts 如果我只有一个“端点类别”,我会有这样的东西: describe('Endpoint category 1', () => { let api: Client = null; before(() => { api

我正在为REST客户机库编写测试,该库必须使用OAuth exchange“登录”服务。为了防止我要测试的每个端点都登录,我想写一些“测试设置”,但我不确定该怎么做

我的测试项目结构:

  • 试验
    • 端点类别1.spec.ts
    • 端点类别2.spec.ts
如果我只有一个“端点类别”,我会有这样的东西:

describe('Endpoint category 1', () => {
  let api: Client = null;

  before(() => {
    api = new Client(credentials);
  });

  it('should successfully login using the test credentials', async () => {
    await api.login();
  });

  it('should return xyz\'s profile', async () => {
    const r: Lookup = await api.lookup('xyz');
    expect(r).to.be.an('object');
  });
});
我的问题:


因为login()方法是这里的第一个测试,所以它可以工作,并且客户机实例也可以用于下面的所有测试。但是,如何进行某种设置,使“登录的api实例”可用于我的其他测试文件?

公共代码应在每次之前移动到

  beforeEach(async () => {
    await api.login();
  });
此时,
应该使用测试凭据成功登录
没有多大意义,因为它不断言任何内容。

您看过吗

您可以在测试函数中输入一个done参数,您将得到一个回调,您必须调用它

done()done(错误/异常)

在之前和之后,也将提供此功能

调用done()时,mocha知道异步代码已经完成

啊。如果您想测试登录,您不应该提供与其他测试的连接,因为在默认配置中无法保证测试顺序

只需测试登录和注销后


如果您需要使用“登录会话”进行更多测试,请使用befores描述一个新的测试。

api.login()返回Promise,但是它可能会引发异常,因此我采用这种方式。在那种情况下我还需要资产吗?我还假设beforeach将在该描述体中的所有测试之前执行。您的观点是,测试环境应该始终相同,因此我也应该在每次测试之前重新登录?第一个问题:是的,您需要在另一个用例中断言登录错误,因为它与“登录成功”完全不同第二种情况:单元测试中的一个常见原则是不将多个测试绑定在一起。这意味着您可以一次性执行所有这些测试,或者每次只执行其中一个测试。但是怎么做呢?这就是重点。我们存根,我们模拟,我们创建一堆数据。然后呢?在每个测试完成后,我们必须将所有这些重置为零,我的意思是,在我们执行每个测试之前,将系统恢复到状态。此外,Estus Flask是正确的,您的代码完全不是单元测试,而是集成。在单元测试中,我们不使用数据库、网络或任何其他昂贵的东西。我们只是对这些东西存根或嘲笑。更重要的是,我们把一个方法放在一个小盒子里,存根或模拟它需要的每个依赖项,控制输入,最后,我们断言输出。这是单元测试。如果登录不成功,它会抛出一个异常。login方法返回一个解析为void的承诺。同样的问题也适用于这里:我希望避免每次测试都再次登录,因为我实际上只需要登录一次就可以测试所有其他端点。@kentor是的,如果在每次失败之前,这将使所有套件测试失败,这是预期的行为。你所描述的事情永远不应该在单元测试中进行,每个测试都应该是一个新的开始,独立于其他测试,因为做相反的事情会影响测试的状态并导致交叉污染。测试中的OAuth是否是一个昂贵的操作,需要执行真正的XHR请求?是的,对于这种特定情况,OAuth exchange总共包含三个请求。只有在测试它的规范中才调用real
login()
应该使用测试凭据成功登录(应该放在不同的
descripe
中,以避免在每个规范之前与其他规范共享)。其他规范使用模拟的
login
,模拟的方式取决于实现,您可以在
api
实例(real
login()
是可以接受的,但在beforeach中是不可取的,因为单元测试应该是快速的)。这就是我希望正确完成的方式。当然,
新客户端(凭据)
也应该在beforeach中完成,以避免交叉污染,这就是为什么我说这些是集成而不是单元测试。有集成测试是一件好事,但它们不能替代单元测试覆盖率。我建议两者都有-它们可以相似和冗余,但它们测试不同的东西。在单元测试中,您可以模拟后端。
before
每个
description
块执行一次,因此它适合您的描述。我不能建议您这样做,因为在不同的测试之间保持一个公共状态从来都不是一个好的做法,这对于单元、集成和e2e都是一样的。是的,我知道,但为了避免此类回调,我正在使用async/await:)
describe('Endpoint category 1', () => {
  let api: Client = null;

  beforeEach(() => {
    api = new Client(credentials);
  });

  afterEach(() => {
    // You should make every single test to be ran in a clean environment.
    // So do some jobs here, to clean all data created by previous tests.
  });

  it('should successfully login using the test credentials', async () => {
    const ret = await api.login();
    // Do some assert for `ret`.
  });

  context('the other tests', () => {
    beforeEach(() => api.login());
    it('should return xyz\'s profile', async () => {
      const r: Lookup = await api.lookup('xyz');
      expect(r).to.be.an('object');
    });
  });
});