【问题标题】:How to pass variable from test to beforeEach hook?如何将变量从测试传递到 beforeEach 钩子?
【发布时间】:2021-05-25 17:41:53
【问题描述】:
describe("SuiteName", () => {
  var numberArray =[1,2,3];

  beforeEach(async () => {
    //I want 'n' from test in this before each method
    console.log("Before Each" + expect.getState().currentTestName + 'number ' + n);
    
  });


    test.each(numberArray)("Tesst Name" , async (n) => {
    console.log("Current parameter is-> " + n);

  });
});

您好,我是 Jest 的新手,想了解如何获取 beforeeach 块中的数值?

【问题讨论】:

  • 您要解决的问题是什么?解决方案是针对它的。 Jest 没有测试上下文的概念,从这个事实出发。您不能将变量从测试传递给 beforeEach,因为 beforeEach 在它之前被评估。
  • 我想为测试的每次迭代创建一个自定义测试报告,并且在每次迭代之前我必须做一些活动,所以我想要那个值,以便我可以根据迭代发布结果
  • 这可能是一个错误的方向,Jest 中有自定义报告和环境允许在那里劫持。无论如何,您尝试做的事情通常可以通过围绕测试 API 创建包装函数来解决。如果需要测试名称,可以自己获取字符串。

标签: arrays jestjs jasmine ts-jest


【解决方案1】:

通过查看笑话代码(文档没有太大帮助),似乎传递给 beforeEach 的回调是使用 done 回调参数调用的,这无济于事。 (来源https://github.com/facebook/jest/blob/0e50f7313837bd005a560cb2161423ab06845733/packages/jest-circus/src/run.tshttps://github.com/facebook/jest/blob/66629be6194f5e107a26f406180a6ed597fb3c55/packages/jest-circus/src/utils.ts

但这并不重要,因为在描述中,beforeEach 和测试共享相同的范围,并且在测试套件中,测试按顺序运行(没有对 testState 的重叠“并发”访问),所以这样做非常好:

describe("SuiteName", () => {
  const testState = { n: undefined };
  var numberArray =[1,2,3];

  beforeEach(async () => {
    //I want 'n' from test in this before each method
    console.log("Before Each" + expect.getState().currentTestName + 'number ' + testState.n);
    
  });

  numberArray.forEach(n => {
    console.log("Current parameter is-> " + n);
    testState.n = n;
    test('Tesst Name for n: ' + n, async () => {
      console.log("Current parameter is-> " + n);
    })
  });
});

问题,您失去了 test.each 的一些好处,因为您将其拆分为共享相同代码的多个测试。但似乎没有办法使用 test.each。

另外,由于 test.each 和 beforeEach 的用例都可以防止重复代码并使测试更具可读性,为什么不将 beforeEach(异步)钩子代码与实际测试链接起来:

describe("SuiteName", () => {
  var numberArray =[1,2,3];

  const forgetBeforeEachWeAreDoingTestEach = (n) => {
    return new Promise((resolve) => {
      //I want 'n' from test in this before each method
      console.log("Before Each" + expect.getState().currentTestName + 'number ' + n);
      resolve();
    });
  });

  test.each(numberArray)('Tesst Name', async (n) => {
    forgetBeforeEachWeAreDoingTestEach(n).then(() => {
        console.log("Current parameter is-> " + n);
    });
  });
});

我用 Promise 完成了上述操作,因为我是老派,但大多数时候从一种转换到另一种非常简单

可能只是:

await forgetBeforeEachWeAreDoingTestEach(n);
console.log("Current parameter is-> " + n);

注意This previous stackoverflow answer here 提供了与第一个(testState)类似的解决方案,带有 sinon.sandbox,但没有解决 test.each 问题(具有多个参数的 1 个测试 VS 具有相同代码的多个测试)

【讨论】:

    【解决方案2】:

    expect.getState() 是内部 API。 Jest 没有测试范围的上下文,它应该由开发人员处理。

    beforeEach 函数在各自的测试之前进行评估,并且不知道之后会发生什么。请注意,beforeEach 是分层的,可以应用于不是从 numberArray 派生的测试。

    在这种情况下,beforeEach 没有作为可重用代码的好处。由于each 函数对于所有这些测试都是通用的,它可以是:

      test.each(numberArray)("Tesst Name" , async (n) => {
        console.log("Before Each number ' + n);
    
        console.log("Current parameter is-> " + n);
      });
    

    【讨论】:

    • 当我想到它时,提出的问题实际上可能是:“我如何链接异步函数”,它与 beforeEach 是“免费的”(beforeEach 用于上面的异步)
    • 我不完全确定 jest 没有提供测试范围的上下文:github.com/facebook/jest/blob/…
    • 但是否可以这样使用并不明显,我同意最好自己实现这样的上下文
    • 它是内部的并且没有记录,所以它可能会随着时间的推移而中断。最初 Jest 使用 Jasmine 的 this 上下文,但后来它被放弃并停止按预期工作。我没有看到链接有太多问题,因为在测试本身中,一切都可以以同样的方式等待。
    • 是的,它看起来像是 jasmine 中 this 的残余。我认为链接也没有任何困难,但我的意思是提出问题的人可能对此有问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-20
    • 2020-04-20
    • 1970-01-01
    相关资源
    最近更新 更多