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.fnget a anonymous mock function. Use to get a anonymous mock function.jest.spyOnInject your expectation into a target object.jest.mockincludejest.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.
-
spyspy 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. -
stubTest stubs are functions (spies) with pre-programmed behavior. Use a stub when you want to:- 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.
- When you want to prevent a specific method from being called directly (possibly because it triggers undesired behavior, such as a XMLHttpRequest or similar).
-
mockMocks (and mock expectations) are fake methods (like spies) with pre-programmed behavior (like stubs) as well as pre-programmed expectations. When to use mocks:- Mocks should only be used for the method under test. In every unit test, there should be one unit under test.
- 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
