首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >摩卡筑巢/复制试验

摩卡筑巢/复制试验
EN

Stack Overflow用户
提问于 2015-07-15 21:36:24
回答 2查看 91关注 0票数 0

给定满足某些不变量的数据结构,我想在各种操作之后测试数据结构实例的状态。做这件事最好的方法是什么?

代码语言:javascript
复制
describe('data-structure', function() {
  var x;

  beforeEach(function() {
    x = getDataStructure();
  });

  describe('satisfies invariants', function() {
    // run tests on 'fresh' x

    it('should ...', function() { 
      // ...
    });

    // ...
  });

  describe('operation 1', function() {
    it('should preserve invariants', function() {
      x.doSomething();
      // run 'satisfies invariants' tests on modified x
    });
  });
});

我考虑过使用afterEach钩子,但我不认为x保存在那里?

代码语言:javascript
复制
afterEach(function() {
  // somehow run 'satisfies invariants' test
});

也许我可以将'satisfies invariants'重构成一个方法,但是如果mocha能够报告每个操作失败的不变量测试,那就太好了。

代码语言:javascript
复制
data-structure
  satisfies invariants
    should satisfy invariant 1 ...
    ...

  operation 1
    should satisfy invariant 1 ...
    ...

  operation 2
    should satisfy invariant 1 ...
    ...

编辑

使用结构

代码语言:javascript
复制
describe('data-structure', function() {
  var x;

  describe('satisfies invariants', function() {
    afterEach(function() {
      it('should satisfy invariant 1', function() { 
        // x.value === a again
        // ...
      });

      // ...
    });

    it('should work after operation 1', function() {
      x = getDataStructure(); // x.value === a
      x.operation1(); // x.value === b
    });

    it('should work after operation 2', function() {
      x = getDataStructure();
      x.operation2();
    });

    // ...
  });
});

似乎没有保留对x的更改。

EN

回答 2

Stack Overflow用户

发布于 2015-07-16 16:32:59

下面是一个例子,如果我忘记了我们讨论过的内容,请告诉我:

代码语言:javascript
复制
var assert = require('assert');

describe('data-structure', function() {
    var x;

    beforeEach(function() {
        // freshly created data structure for each describe block below
        x = getDataStructure;
    });

    describe('satisfies invariants', function() {
            after(function() {
                // it executes those tests only once after all the it block below
                assert(x); // put your tests here
            });

            it('op 1.1', function() {
                do_something_on(x);
            });

            it('op 1.2', function() {
                // keep in mind that x is the same instance of the previous test
                do_something_else_on(x);
            });

            // so on
    });

    describe('satisfies something else', function() {
            // here you have a new instance of x, because of the outer beforeeach

            after(function() {
                // it executes those tests only once after all the it block within this describe block
                assert(x); // put your tests here
            });

            it('op 2.1', function() {
                do_something_on(x);
            });

            it('op 2.2', function() {
                // keep in mind that x is the same instance of the previous test, but not the one used in 1.2
                do_something_else_on(x);
            });

            // so on
    });

    // so on
});

这段代码应该让您知道哪个实例是可以访问的,以及在哪里访问的。如果它缺少什么,让我知道,我会去修理它。

票数 0
EN

Stack Overflow用户

发布于 2015-07-16 16:40:42

问题

摩卡不支持将it放入钩子中,就像您在最后一个片段中所做的那样。(afterEach是一个钩子)在一些琐碎的情况下,你可能会得到想要的行为,但这只是运气。一旦您转到更复杂的测试套件,您就不会得到您期望的行为。

此外,我认为afterEach是进行这种测试的错误位置。您应该只使用钩子来设置和拆卸您的测试环境,而不是对代码的状态执行断言。摩卡将钩子中的任何故障视为“测试套件被破坏,中止!”而不是测试失败。例如,看看这个例子:

代码语言:javascript
复制
var assert = require('assert');

describe("test", function () {
    var x;

    beforeEach(function () {
        x = { foo: 'something' };
    });

    afterEach(function () {
        assert(x.foo === 'something');
    });

    it("one", function () {});

    it("two", function () {
        x.foo = 'something else';
    });

    it("three", function () {});
});

理论上,测试three不应该运行是没有理由的,但是当afterEach钩子在测试two运行后发生故障时,Mocha就会停止在那里运行测试。输出(省略最后的堆栈跟踪)是:

代码语言:javascript
复制
  test
    ✓ one 
    ✓ two 
    1) "after each" hook


  2 passing (14ms)
  1 failing

注意two是如何标记为传递的,但是钩子失败了。请注意three是如何从未尝试过的。一旦钩子出现故障,摩卡就会停在那里。

解决方案

您应该创建一个函数,您可以从每个测试中调用这个函数来测试不变量。例如:

代码语言:javascript
复制
var assert = require('assert');

describe("test", function () {
    var x;

    beforeEach(function () {
        x = { foo: 'something' };
    });

    function testInvariant() {
        assert(x.foo === 'something');
    }

    it("one", function () {
        testInvariant();
    });

    it("two", function () {
        x.foo = 'something else';
        testInvariant();
    });

    it("three", function () {
        testInvariant();
    });
});

如果您在上面的代码上运行Mocha,您将得到(同样,省略了最后的堆栈跟踪):

代码语言:javascript
复制
  test
    ✓ one 
    1) two
    ✓ three 


  2 passing (10ms)
  1 failing

two被标记为失败,Mocha继续运行three,这是成功的。

如果您不想在每个测试中编写testInvariant(),您可以创建一个函数来为您添加它。例如:

代码语言:javascript
复制
var assert = require('assert');

describe("test", function () {
    var x;

    beforeEach(function () {
        x = { foo: 'something' };
    });

    function makeTest(name, fn) {
        it(name, function () {
            fn();
            assert(x.foo === 'something');
        });
    }

    makeTest("one", function () {
    });

    makeTest("two", function () {
        x.foo = 'something else';
    });

    makeTest("three", function () {
    });
});

这将产生与前一个代码片段相同的输出。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31441583

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档