最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to add global commands to Jest like describe and it? - Stack Overflow

programmeradmin0浏览0评论

I'm writing a little testing tool for Jest (just to learn). It is called assertTruthy(msg, fn, args), expects a message, a function and arguments and should pass if the thing that is returned when the function is invoked with the arguments is truthy and fail if its not.

I would like to add it to Jest, so that you could call it without importing it in every environment.

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

I know Jest has setupFiles and setupFilesAfterEnv but I can't figure out how to use them to achieve this.

How do you add mands to Jest?

PS: On a single project basis (in CRA) I managed to do this like this:

// in src/setupFiles.js
const assertTruthy = // function definition ...
global.assertTruthy = assertTruthy

I'm writing a little testing tool for Jest (just to learn). It is called assertTruthy(msg, fn, args), expects a message, a function and arguments and should pass if the thing that is returned when the function is invoked with the arguments is truthy and fail if its not.

I would like to add it to Jest, so that you could call it without importing it in every environment.

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

I know Jest has setupFiles and setupFilesAfterEnv but I can't figure out how to use them to achieve this.

How do you add mands to Jest?

PS: On a single project basis (in CRA) I managed to do this like this:

// in src/setupFiles.js
const assertTruthy = // function definition ...
global.assertTruthy = assertTruthy
Share Improve this question edited May 16, 2019 at 19:11 TylerH 21.1k77 gold badges79 silver badges112 bronze badges asked May 16, 2019 at 18:49 J. HestersJ. Hesters 14.8k34 gold badges155 silver badges267 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 9 +100

Add global functions to Jest

In order to add global functions to jest, you need to define setupFiles in your configuration and attach that function to the global object in the setup file:

module.exports = {
  // ...
  setupFiles: ['<rootDir>/setupFile.js'],
  // ...
};

so if you want to do something very similar to it, I would suggest you do something like this:

// /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`

Supporting the same interface as jest.It

Here's an example from the Airbnb library airbnb/jest-wrap where they wrapped the describe function. If you want to implement the jest.It interface, you'll also need to implement assertTruthy.todo, assertTruthy.skip, assertTruthy.only, & assertTruthy.each (check out the it interface). todo and skip are pretty easy since you want to do exactly the same as the original ones.

For each & only, we need to change the it function inside our implementation. A simple way to support only is by using a closure and passing the correct it function from the closure's inpu. each can be a little more plex to implement.

// /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]);

How to use in test files

If you're using typescript for writing jest test, the first thing you'll need to do is declare your new function somewhere:

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

declare const assertTruthy: (message: string, func: IGenericFunction, ...args: any[]) => any;

With javascript, you can skip that step.

After that, just use it like you use describe and it:

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

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

  test("another test", () => {
    // ...
  });
});

and jest will treat this as any other it function

Using as a node_module dependency

If you want to create a library from this, you can basically just pass a node_modules path to the setupFiles array.

For example, with this repository, you can do as follows:

  1. Install using npm install --save-dev @kibibit/jest-utils
  2. Add the following to your jest configuration
  3. Use the function as described above
module.exports = {
  // ...
  setupFiles: ['node_modules/@kibibit/jest-utils/lib/jest-utils.js'],
  // ...
};

and it should work the same as importing it locally.

发布评论

评论列表(0)

  1. 暂无评论