jest mock simple usage

1,336 阅读3分钟

Jest is a populate js testing framework.It is maintain by Facebook JavaScript Foundation team.It cover both front-end and back-end testing solution.

Jest Mock vs Sinon.JS

  • Jest mock

First of all, please remember that jest mock have three ways for mocking:

  • jest.fn get a anonymous mock function. Use to get a anonymous mock function.
  • jest.spyOn Inject your expectation into a target object.
  • jest.mock include jest.genFromModule, jest.doMock, etc. Jest Automatically set all exports of a module to the Mock Function.Use to replace target module.

Jest mock is a part of Jest. Distinguish from Mocha, jest has its own mock module. You don't need to add extra mock module when you use Jest as your testing framework. Also Jest include assertion module expect, which means you don't need to install a assertion module like should or expect.

sample usage

describe('demo mock function', () => {
  it('should return ok', () => {
    const fakeFn = jest.fn(() => return 'ok')
    const result = fakeFn();
 
    expect(result).toEqual('ok');
  });
});

  • Sinon.JS

As sinon official description:

Standalone test spies, stubs and mocks for JavaScript. Works with any unit testing framework.

Sinon is not a testing framework, it work with any testing framework. You can also use Sinon replace Jest mock in your jest test case. Sinon is more simple and easy to use than Jest mock. If you are a newer, sinon should be your best choice. Sinon has a distinct definition for spy, stub and mock.You will clear know your expectation behaviours and when use which kind of mock function.

  • spy spy is the base mocking module of sinon.Allow user to control is a function that records arguments, return value, the value of this and exception thrown (if any) for all its calls.

  • stub Test stubs are functions (spies) with pre-programmed behavior. Use a stub when you want to:

    1. Control a method’s behavior from a test to force the code down a specific path. Examples include forcing a method to throw an error in order to test error handling.
    2. When you want to prevent a specific method from being called directly (possibly because it triggers undesired behavior, such as a XMLHttpRequest or similar).
  • mock Mocks (and mock expectations) are fake methods (like spies) with pre-programmed behavior (like stubs) as well as pre-programmed expectations. When to use mocks:

    1. Mocks should only be used for the method under test. In every unit test, there should be one unit under test.
    2. If you want to control how your unit is being used and like stating expectations upfront (as opposed to asserting after the fact), use a mock.

sample usage

describe('demo mock function', () => {
  it('should return ok', () => {
    const fakeFn = sinon.fake.returns('ok');
    const result = fakeFn();
    expect(result).toEqual('ok');
  });
});

spy

What is a test spy?

A test spy is a function that records arguments, return value, the value of this and exception thrown (if any) for all its calls. There are two types of spies: Some are anonymous functions, while others wrap methods that already exist in the system under test.

Sinon spy

You can easy generate a anonymous spy or wrap spy for existing object(whole object methods or a single method)

const anonymousSpy = sinon.spy();
const obj = { 
  a: () => {},
  b: sin.fake.returns(true),
};
// wrap all methods
const allSpy = sinon.spy(obj);
// 
const singleSpy = sinon.spy(obj, 'b');

Jest spy Many demo code from google is about jest.spyOn(obj, 'funcName'), if you want to generate a pure spy function, it makes you confusing, I have no object, how can I do? Yep, It is confusing me too. You can't get a anonymous spy function directly, you can use jest.fn instead.

stub

st stubs are functions (spies) with pre-programmed behavior.

Jest mock: there is none stub conception, you can use jset.fn to alert the stub’s behavior.

const stub = jest.fn().mcokReturnValue(true);
const res = stub();
expect(sub).toHaveBeenCalled();
expect(res).toEqual(true);

Sinon: Sinon support the full test spy API in addition to methods which can be used to alter the stub’s behavior.

const callback = sinon.stub();
callback.withArgs(42).returns(1);
callback.withArgs(1).throws("name");

callback(); // No return value, no exception
callback(42); // Returns 1
callback(1); // Throws Error("name")

mock

Sometimes you want to skip the other module imported in your test function and assume it run as your expected. You need to use mock function to verify your expectation.

Jest there are serveral ways to setup a mock behavior. jest.mock, jest.genFromModule... For example, your want to replace fs.readFileSynnc function.

jest.mock('fs', () => {
  return {
    readFileSynnc: jest.fn(_ => Buffer.from('some data'))    
  };
});

In most scenarios, you need to reload imported modules or you will find that your mock doesn't work. Before you setup a mock, you need to put jest.reestModules() in front of your test code.

Sinon Different from jest.mock as you setup you mock in your test case, sinon have been help to replace the target module.

const JQuery = require('jquery');
sinon.mock(jQuery).expects("ajax").atLeast(2).atMost(5);
# do some works
jQuery.ajax.verify();

This is my first English article