Hello everyone,
i would like to request a feature, if it is not implemented yet.
i just stared testing with jest and asked myself how to test an express application efficiently.
What is the current behavior?
I wanted to write the tests on 2 points:
When the application talks to my mongoose model
When the application answers the request
So i wrote following code:
describe("GET route", function() {
// Preperation
// Mocking express req and res
var httpMocks = require.requireActual("node-mocks-http");
var req = httpMocks.createRequest({
method: 'GET',
url: '/'
});
var res = httpMocks.createResponse({
eventEmitter: require('events').EventEmitter
});
//Tests
//Testing the default request
it('tests the empty req', (done) => {
jest.mock("../model/mymongoosemodel", function() {
return function() {
//mocking the behavior of the mongoose model (find and sort => chainable) returning a promise
var model = function() {};
model.find = function() {
var prom = new Promise(function(resolve, reject) {
resolve([]);
});
prom.sort = function() {
//writing my expect statements
expect(arguments[0]).toBeDefined();
return prom;
};
return prom;
};
return model;
};
});
res.on('end', function() {
var data = res._getData();
expect(res.statusCode).toBe(200);
expect(data).toBeDefined();
done();
});
require("myroute")(req, res);
});
//Tests
//Testing the skip request
it('tests the skip req', (done) => {
jest.mock("../model/mymongoosemodel", function() {
return function() {
//mocking the behavior of the mongoose model (find sort and skip => chainable) returning a promise
var model = function() {};
model.find = function() {
var prom = new Promise(function(resolve, reject) {
resolve([]);
});
prom.skip = function() {
return prom;
};
prom.sort = function() {
expect(arguments[0]).toBeDefined();
return prom;
};
return prom;
};
return model;
};
});
res.on('end', function() {
var data = res._getData();
expect(res.statusCode).toBe(200);
expect(data).toBeDefined();
done();
});
req.url += "10";
require("myroute")(req, res);
});
});
What is the expected behavior?
If i run this, the second test fails because there is no skip in my mongoose model.
I analyzed that and found that the second jest.mock call on ../model/mymongoosemodel did not override the first one.
So now my question:
Is it possible to do something like a remock on already mocked modules?
Thanks in advance
jpolack
Run Jest again with --debug and provide the full configuration it prints. Please mention your node and npm version and operating system.
jest version = 17.0.3
test framework = jasmine2
config = {
"testPathDirs": [
"/Users/jpolack/workspace/Server/__tests__"
],
"setupTestFrameworkScriptFile": "/Users/jpolack/workspace/Server/testapp.js",
"rootDir": "/Users/jpolack/workspace/Server",
"name": "-Users-jpolack-workspace-Server",
"setupFiles": [],
"testRunner": "/usr/local/lib/node_modules/jest/node_modules/jest-cli/node_modules/jest-jasmine2/build/index.js",
"automock": false,
"bail": false,
"browser": false,
"cacheDirectory": "/var/folders/1n/wqmw_88514g656zcmvsp0gvc0000gn/T/jest",
"coveragePathIgnorePatterns": [
"/node_modules/"
],
"coverageReporters": [
"json",
"text",
"lcov",
"clover"
],
"expand": false,
"globals": {},
"haste": {
"providesModuleNodeModules": []
},
"mocksPattern": "__mocks__",
"moduleDirectories": [
"node_modules"
],
"moduleFileExtensions": [
"js",
"json",
"jsx",
"node"
],
"moduleNameMapper": {},
"modulePathIgnorePatterns": [],
"noStackTrace": false,
"notify": false,
"preset": null,
"resetMocks": false,
"resetModules": false,
"snapshotSerializers": [],
"testEnvironment": "jest-environment-jsdom",
"testPathIgnorePatterns": [
"/node_modules/"
],
"testRegex": "(/__tests__/.*|\\.(test|spec))\\.jsx?$",
"testURL": "about:blank",
"timers": "real",
"transformIgnorePatterns": [
"/node_modules/"
],
"useStderr": false,
"verbose": null,
"watch": false,
"cache": true,
"watchman": true
}
I'm interested on this as well... I'd lke to be able to mock modules only for specific asserts, like this:
describe('', () => {
it('',() => {
jest.mock('module', () => {});
// here `module` will be mocked
})
it('',() => {
// here `module` points to its original source
})
})
I'm not sure if that's already supported though, but I looked in the docs, and were not able to find anything related to it :(
If you'd like to mock a module that was previously required, you'll have to call jest.resetModules() and re-require it.
Example:
let module = require('module');
jest.mock('module');
jest.resetModules();
module = require('module'); // this is a fresh, mocked copy
in beforeEach that may look like this:
let module;
beforeEach(() => {
jest.mock('module');
jest.resetModules();
module = require('module'); // this is a fresh, mocked copy
});
Most helpful comment
If you'd like to mock a module that was previously required, you'll have to call
jest.resetModules()and re-require it.Example:
in
beforeEachthat may look like this: