【问题标题】:What is the purpose of Mocha's #beforeEach when you can just run code inside the #describe scope?当您可以在#describe 范围内运行代码时,Mocha 的#beforeEach 的目的是什么?
【发布时间】:2017-02-28 18:32:18
【问题描述】:

我正在从article 中学习 TDD,作者谈到了 Mocha 的 beforeEach 将如何在每个断言之前为您运行代码。但我不明白当你可以在描述范围内运行代码时为什么需要这样做。

describe('Test suite for UserComponent', () => {
  beforeEach(() => {
    // Prevent duplication
    wrapper = shallow(<UserComponent
                            name={ 'Reign' }
                            age={ 26 } />);
  });

  it('UserComponent should exist', () => {
    expect(wrapper).to.exist;
  });

  it('Correctly displays the user name and age in paragraphs wrapped under a parent div', () => {
    expect(wrapper.type()).to.equal('div');
    // more code...
  });
});

但不使用 beforeEach 仍然可以工作 -

describe('Test suite for UserComponent', () => {

wrapper = shallow(<UserComponent
                        name={ 'Reign' }
                        age={ 26 } />);

  it('UserComponent should exist', () => {
    expect(wrapper).to.exist;
  });

  it('Correctly displays the user name and age in paragraphs wrapped under a parent div', () => {
    expect(wrapper.type()).to.equal('div');
    // more code...
  });
});

【问题讨论】:

  • 如果要在每次测试前调用ajax请求?或分贝请求?还是清除变量?

标签: javascript unit-testing testing tdd mocha.js


【解决方案1】:

beforeEacheach 测试之前执行。当代码从beforeEach 移动到直接在传递给describe 的函数内部时,此迭代将丢失。然而,这还不是全部。

某些情况下,直接在传递给describe的函数内部执行的代码可以执行与beforeEach挂钩相同的任务。 例如,如果它的功能是在 describe 块中初始化测试本地的只读结构,那么您可以跳过 beforeEach 挂钩。

但是,Mocha 会立即执行所有传递给 describe 调用的回调,而 beforeEach 调用会注册传递给它的函数以供将来执行,并且它将被执行仅在需要时。如果初始化开销很大,最好使用beforeEach 钩子,因为如果您使用--grep 只选择一些测试,或者使用it.only 运行单个测试,那么 Mocha 将只运行钩子与它将实际运行的测试有关。 如果您在describe 中有初始化代码,则 Mocha 无法跳过它,因此您将每次支付初始化费用。但是,如果您要使用钩子并且数据是不可变的,那么beforebeforeEach 更好,因为它只会运行一次,而不是在每次测试之前。

在某些情况下,直接在传递给describe 的函数中运行代码根本行不通。 想象一下,sharedResource 是所有测试都需要使用的资源.例如,它可以是携带状态的第三方库。有些测试需要将其设置为某个状态。其他测试需要它处于不同的状态。这不起作用:

"use strict";

const assert = require('assert');

let sharedResource;

describe("in condition a", () => {
    sharedResource = true;

    it("sharedResource is true", () => assert(sharedResource));
});

describe("in condition b", () => {
    sharedResource = false;

    it("sharedResource is false", () => assert(!sharedResource));
});

第一次测试会失败,因为关键语句的执行顺序是:

  1. sharedResource = true;
  2. sharedResource = false;
  3. assert(sharedResource);
  4. assert(!sharedResource);

使用beforeEach 可以轻松解决此问题。这运行良好:

"use strict";

const assert = require('assert');

let sharedResource;

describe("in condition a", () => {
    beforeEach(() => {
        sharedResource = true;
    });

    it("sharedResource is true", () => assert(sharedResource));
});

describe("in condition b", () => {
    beforeEach(() => {
        sharedResource = false;
    });

    it("sharedResource is false", () => assert(!sharedResource));
});

【讨论】:

  • 我明白为什么第一次测试会失败,但是为什么 sharedResource 不在第一次测试的范围内时设置为 false?它是在之后出现的,并且仅在第二次测试的范围内设置为 false,所以它不应该只适用于第二次测试吗?
  • 正如我所写的“Mocha 会立即执行所有传递给描述调用的回调”。我确实提到beforeEach 注册了钩子以供将来执行,但没有明确说明it 也是如此。当 Mocha 执行it 时,只是记录测试以备将来执行,不会立即执行。这个answer进入执行顺序的细节。
猜你喜欢
  • 1970-01-01
  • 2013-10-18
  • 2021-07-30
  • 1970-01-01
  • 2021-01-25
  • 2012-08-29
  • 2019-03-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多