简体   繁体   中英

Jest: How to mock a library in node_modules?

I'm trying to write a test for code that uses node-forge. For some reason, the test hangs when I call forge.md.sha256.create(); :

  import forge from "node-forge";

  const privateKey = "foo";
  const storagePin = "bar";

  const md = forge.md.sha256.create();
  md.update(privateKey + storagePin);

  const metadataKey = md.digest().toHex();

As a workaround, I am trying to mock the implementation of that method so that it just returns a hardcoded string:

import forge from "node-forge";
jest.mock("node-forge");

forge.mockImplementation(() => {
  return {
    md: {
      sha256: {
        create: () => {
          return {
            update: () => {},
            digest: () => {
              toHex: () => "foobar";
            }
          };
        }
      }
    }
  };
});


// tests

However, my tests keep failing:

TypeError: _nodeForge2.default.mockImplementation is not a function

  at Object.<anonymous> (src/redux/epics/authentication-epic.test.js:20:27)
      at new Promise (<anonymous>)
  at Promise.resolve.then.el (node_modules/p-map/index.js:46:16)
  at processTicksAndRejections (internal/process/next_tick.js:81:5)

The weird thing is, this strategy works perfectly fine when I try to mock my own files.

What is the proper way of mocking a 3rd party library?

did you try like this? More about this here .

jest.mock('node-forge', () => ({
  md: {
    sha256: {
      create: () => ({
        update: () => {},
        digest: () => ({
          toHex: () => 'foobar'
        }),
      }),
    },
  },
}));

The default export isn't a function so Jest auto-mocking doesn't replace the default export with a mock function...

...but the default export is an object.

From Exploring ES6 :

...while you can't change the values of imports, you can change the objects that they are referring to.

So you can just set the md property on the object to your mock:

import forge from 'node-forge';
jest.mock('node-forge');

const toHex = jest.fn(() => 'foobar');
const digest = jest.fn(() => ({ toHex }));
const update = jest.fn();

forge.md = {  // <= set the md property to your mock
  sha256: {
    create: jest.fn(() => ({
      update,
      digest
    }))
  }
};

test('code uses the mock', () => {
  require('./path to your code');  // <= the mock will be used in the required code
  expect(forge.md.sha256.create).toHaveBeenCalled();  // Success!
  expect(update).toHaveBeenCalledWith('foobar');  // Success!
  expect(digest).toHaveBeenCalled();  // Success!
  expect(toHex).toHaveBeenCalled();  // Success
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM