Javascript 每次测试前是否在摩卡套件中设置变量?

Javascript 每次测试前是否在摩卡套件中设置变量?,javascript,mocha.js,Javascript,Mocha.js,我想先设置一些变量,在执行测试之前, 我找到了这个解决方案 但是,我不知道如何将变量传递到回调函数中,我这样做会导致未定义 makeSuite('hello', (context) => { it('should return', () => { assert.strictEqual(1, 1) }) }) makeSuite('world', (context) => { it('should return', () => {

我想先设置一些变量,在执行测试之前, 我找到了这个解决方案

但是,我不知道如何将变量传递到回调函数中,我这样做会导致未定义

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);
    })
}

我想将变量传递到回调中的原因是,我需要在每个hook之前在
设置许多私有变量,我不想为所有的测试重复我的代码。

传递到
descripe
的回调会立即调用,但是在每个
之前的
钩子会在稍后的测试执行时调用。因此,当调用
cb(age)
时,
age
具有值
undefined
age
稍后设置为
“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上下文中

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();
    })
}

但是,我不认为将变量注入摩卡上下文是一个好的做法,@Louis提供的答案将是更好的解决方案

我从@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);
});

非常聪明的解决方案!;),我确实找到了另一种方法,就是注入到
摩卡上下文中
,但我认为这不是一个好的做法!是的,我不喜欢把这个混为一谈,因为它是由摩卡提供的,包含了部分公共API和一些私有值。很多时候,在
中添加一些东西是可行的,但是有一天,新版本的摩卡咖啡可能会与您选择的变量发生冲突。例如,现在设置
this.timeout
this.retries
,将覆盖Mocha自己的功能。