代码之家  ›  专栏  ›  技术社区  ›  Christopher Francisco

Mocha-我应该直接在descripe()块或before()内初始化存根吗

  •  3
  • Christopher Francisco  · 技术社区  · 6 年前

    我需要对存根变量的引用,以便 reset() restore() 在…上 afterEach() after() 回调。

    我最初的方法是在 describe() 块,以便可以在回调中访问变量:

    describe('my SUT', () => {
      const myStub = sinon.stub(myModule, 'itsMethod');
    
      after(() => {
        myStub.restore();
      });
    });
    

    然而,我想知道使用 before() 初始化回调:

    describe('my SUT', () => {
      let myStub = null;
    
      before(() => {
        myStub = sinon.stub(myModule, 'itsMethod');
      });
    
      after(() => {
        myStub.restore();
      });
    });
    

    使用第二种方法有什么好处吗(如果出现问题,可能会有更多的输出等)?

    如果是这样的话,有很多 let myVar = null 一开始就四处闲逛,还有其他方法吗?

    2 回复  |  直到 6 年前
        1
  •  0
  •   sripberger    6 年前

    我建议使用 beforeEach afterEach 代替 before after 创建和清理大多数存根和间谍。

    当然,这取决于具体情况——如果你只有一个,那没有什么区别 it 在您的 describe 块但如果您这样做了,通常最好每个测试都有自己的存根的新副本。这样,您就可以在不依赖于其他测试的每个测试中针对存根的状态(其调用计数、调用参数等)编写断言。

        2
  •  0
  •   Antonio Narkevich    6 年前

    执行令可能存在问题。

    问题是,descripe块的主体在任何 before , after it 阻碍。

    假设我们有一个包含2个方法的api,我们将它们分为2个不同的 describe 的:

    const sinon = require('sinon');
    
    const api = {
        getFoo() { console.log('executed Foo') },
        getBar() { console.log('executed Bar') }
    };
    
    describe('spec 1', () => {
        const stub = sinon.stub(api, 'getFoo').callsFake(() => {console.log('executed Foo stub')});
        console.log('Replaced getFoo with a stub');
    
        it('test 1', () => {
            console.log('running test 1');
    
            // We expect a stub to be executed here.
            api.getFoo();
            // We expect an actual method here.
            // But IN FACT we are executing a stub from the next describe block.
            api.getBar();
        });
    
        after(() => stub.restore());
    });
    
    describe('spec 2', () => {
        const stub = sinon.stub(api, 'getBar').callsFake(() => {console.log('executed Bar stub')});
        console.log('Replaced getBar with a stub');
    
        it('test 2', () => { console.log('running test 2'); });
    
        after(() => stub.restore());
    });
    
    /* Replaced getFoo with a stub
    Replaced getBar with a stub
    spec 1
    running test 1
    executed Foo stub
    executed Bar stub */

    正如您所看到的,在第一次测试开始之前,我们已经应用了两个存根。这是一种不确定的行为。

    要解决任何问题并使代码干净,您可以使用 sinon sandboxes + 之前 之后 块(或前后)。

    一切都将按正确的顺序进行存根/取消存根+一个存根可以包含无限数量的存根/间谍/等,并且可以在拍摄时恢复。

    const sandbox = sinon.createSandbox();
    
    describe('spec 1', () => {
        before(() => {
            sandbox.stub(api, 'getFoo').callsFake(() => { console.log('executed getFoo stub'); });
        });
    
        after(() => sandbox.restore());
    
        it('test 1', () => {
            // ...
        });
    });

    他们在文档中也给出了一个很好的例子。