【问题标题】:Setup variable in mocha suite before each test?每次测试前在摩卡套件中设置变量?
【发布时间】:2017-02-23 10:06:59
【问题描述】:

我想在执行测试之前先设置一些变量, 我找到了这个解决方案,Running Mocha setup before each suite rather than before each test

但是,我不知道如何将变量传递给我的回调,他们这样做我会得到未定义

makeSuite('hello', (context) => {
    it('should return', () => {
        assert.strictEqual(1, 1)
    })
})
makeSuite('world', (context) => {
    it('should return', () => {
        console.log(context) // undefined
        assert.strictEqual(1, 1)
    })
})

function makeSuite(name: string, cb: (context: any) => any) {
    let age: string;
    describe(name, () => {
        beforeEach(() => {
            age = '123'
        })

        cb(age);
    })
}

之所以要将变量传递给回调,是因为我将有许多私有变量需要在beforeEach 挂钩处设置,并且我不想为所有测试重复我的代码。

【问题讨论】:

    标签: javascript mocha.js


    【解决方案1】:

    传递给describe 的回调会立即被调用,但您的beforeEach 钩子会在测试执行时稍后被调用。所以当cb(age) 被调用时,age 的值为undefinedage 稍后设置为 "123"cb 已经获得了其值的副本,因此它没有效果。为了让cb 看到更改,您必须将引用传递给您然后变异的对象。像这样的:

    makeSuite('world', (context) => {
        it('should return', () => {
            console.log(context.age)
        })
    })
    
    function makeSuite(name, cb) {
        describe(name, () => {
            let context = {
                age: undefined,
            };
            beforeEach(() => {
                context.age = '123';
            });
    
            cb(context);
        });
    }
    

    (我已经删除了 TypeScript 类型注释,以便它作为纯 JavaScript 运行。无论如何,注释对于解决问题并不重要。)

    【讨论】:

    • 非常聪明的解决方案! ;),我确实找到了另一种方法,就是注入mocha context,但我认为这不是一个好习惯!
    【解决方案2】:

    还有一种方法,就是将变量注入mocha context

    makeSuite('world', function() {
        it('should return', function() {
            // read the variable as shown below
            console.log((this as any).age); // 123
        })
    })
    
    function makeSuite(name: string, cb: () => any) {
        describe(name, function() {
            beforeEach(function() {
                // inject the desired variable into the mocha context
                (this as any).age = 123;
            })
    
            cb();
        })
    }
    

    但是,我认为将变量注入 mocha 上下文不是一个好习惯,@Louis 提供的答案会是更好的解决方案

    【讨论】:

    • 是的,我不喜欢搞乱this,因为它是由 Mocha 提供的,并且包含它的部分公共 API 和一些私有值。很多时候向this 添加一些东西会起作用,但有一天可能会出现一个新版本的 Mocha,它与您选择的变量发生冲突。例如,现在设置 this.timeoutthis.retries 会覆盖 Mocha 自己的函数。
    【解决方案3】:

    我从@Louis 正在做的事情开始,但后来发现(在我的情况下)围绕它创建函数会更好。这样,我可以切换之后和之前的操作。我还需要之前、之后和异步。

    function itWithSetup(name, callback, doBefore = true, doAfter = true) {
    
      let context = null;
      if (doBefore) {
        before(async () => {
         context = await getContext();
        });
      }
      it(name, async () => {
        await callback(context);
      });
      if (doAfter) {
        after(async () => {
          await clearContext();
        });
      }
    }
    
    describe("test with context", () => {
    
      itWithSetup("unit test", async (message) => {
    
        await testWithContext(context, otherConditions);
    
      }, true, true);
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-07
      • 1970-01-01
      • 1970-01-01
      • 2015-06-27
      • 1970-01-01
      • 2017-05-02
      • 1970-01-01
      • 2014-04-06
      相关资源
      最近更新 更多