如何像描述和添加全局命令到Jest?

J. *_*ers 5 javascript jestjs

我正在为Jest写一个小的测试工具(仅供学习)。它被称为assertTruthy(msg, fn, args),需要一条消息,一个函数和参数,并且如果使用参数调用该函数时返回的内容为真,则应通过,否则为false。

我想将其添加到Jest,以便您可以调用它而无需在每个环境中导入它。

describe('someFn()', () => {
  // like 'it', 'describe' and 'expect' it should just be available here
  it('is a function', () => {
    expect(typeop someFN).toEqual('Function');
  });

  assertTruthy('it should return true', someFn, 3, 4);
});
Run Code Online (Sandbox Code Playgroud)

我知道Jest有setupFilessetupFilesAfterEnv但我不知道如何使用它们来实现这一目标。

如何将命令添加到Jest?

PS:在单个项目的基础上(在CRA中),我设法做到了这一点:

// in src/setupFiles.js
const assertTruthy = // function definition ...
global.assertTruthy = assertTruthy
Run Code Online (Sandbox Code Playgroud)

Tha*_*guy 5

向 Jest 添加全局函数

为了向jest添加全局函数,您需要setupFiles在配置中定义并将该函数附加到设置文件中的全局对象:

module.exports = {
  // ...
  setupFiles: ['<rootDir>/setupFile.js'],
  // ...
};
Run Code Online (Sandbox Code Playgroud)

所以如果你想做一些与 非常相似的事情it,我建议你做这样的事情:

// /setupFile.js

// in order to change an existing function (not youre case):
global.it = function(description, fn) { /* ... */ };

// this is how you define a new function globally
global.assertTruthy = (message, func, ...args) => {
  return global.it(message, () => {
    expect(func(...args)).toBeTruthy();
  });

// optional: implementing the same interface as `jest.It`
Run Code Online (Sandbox Code Playgroud)

支持相同的接口 jest.It

这是Airbnbairbnb/jest-wrap中的一个示例,他们在其中包装了 describe 函数。如果要实现jest.It接口,还需要实现assertTruthy.todo, assertTruthy.skip, assertTruthy.only, & assertTruthy.each查看it接口)。todo并且skip非常简单,因为您想要做与原始完全相同的事情。

对于each& only,我们需要更改实现中的it函数。一种简单的支持方法only是使用闭包并it从闭包的输入中传递正确的函数。each实现起来可能有点复杂。

// /setupFile.js

// normaly, use the jest `it` function
global.assertTruthy = assertTruthyCreator(it);

// bypass for todo and skip
global.assertTruthy.todo = global.it.todo;
global.assertTruthy.skip = global.it.skip;
// only calls the same function but uses `only` internaly
global.assertTruthy.only = assertTruthyCreator(it.only);
// special case which needs special implementation
// see usage below
global.assertTruthy.each = assertTruthyCreator(it.each, true);

function assertTruthyCreator(itFunc, withTable) {
  if (withTable) {
    return (message, func, ...args) => {
      return itFunc(args)(message, (...caseArgs) => {
        expect(func(...caseArgs)).toBeTruthy();
      });
    };
  }

  return (message, func, ...args) => {
    return itFunc(message, () => {
      expect(func(...args)).toBeTruthy();
    });
  };
}

// usage:
assertTruthy.each(
  'add numbers',
  (a, b) => a + b,
  [2, 4],
  [4, 5],
  [7, 9]);

Run Code Online (Sandbox Code Playgroud)

如何在测试文件中使用

如果您使用 typescript 编写 jest 测试,您需要做的第一件事就是declare在某处添加新函数:

interface IGenericFunction {
  (...args: any[]): any;
}

declare const assertTruthy: (message: string, func: IGenericFunction, ...args: any[]) => any;
Run Code Online (Sandbox Code Playgroud)

使用 javascript,您可以跳过该步骤。

之后,就像使用describeand一样使用它it

const funcToTest = (a: number, b: number) => a + b;

describe("Test Suite", () => {
  assertTruthy('this ran with assertTruthy', funcToTest, 5, 3);

  test("another test", () => {
    // ...
  });
});
Run Code Online (Sandbox Code Playgroud)

并且 jest 会将其视为任何其他it功能 玩笑运行结果

作为node_module依赖使用

如果你想从中创建一个库,你基本上可以只传递一个node_modules路径到setupFiles数组。

例如,使用存储库,您可以执行以下操作:

  1. 安装使用 npm install --save-dev @kibibit/jest-utils
  2. 将以下内容添加到您的jest 配置中
  3. 使用上述功能
module.exports = {
  // ...
  setupFiles: ['node_modules/@kibibit/jest-utils/lib/jest-utils.js'],
  // ...
};
Run Code Online (Sandbox Code Playgroud)

它应该与在本地导入它的工作方式相同。