jest + supertest:如何重置模拟依赖
jest + supertest: how to reset the mocked dependency
在 supertest 使用一次依赖项后,我无法重置依赖项的笑话模拟。感谢任何帮助或提示。
以下是我的api超测测试:
import request from 'supertest';
import router from '../index';
const app = require('express')();
app.use(router);
jest.mock('config', () => ({}));
jest.mock('express-request-proxy', () => data => (req, res, next) =>
res.json(data),
);
beforeEach(() => {
jest.resetAllMocks();
});
describe('GET /', () => {
it('should get all stuff', () =>
request(app)
.get('')
.expect(200)
.expect('Content-Type', /json/)
.then(response => {
expect(response.body).toMatchSnapshot(); // all good here
}));
it('should get all stuff when FOO=bar', async () => {
jest.mock('config', () => ({
FOO: 'bar',
get: key => key,
}));
// >> HERE <<
// config.FOO is still undefined!
// reseting mocks did not work ...
await request(app)
.get('')
.expect(200)
.expect('Content-Type', /json/)
.then(response => {
expect(response.body.query).toHaveProperty('baz'); // test fails ...
});
});
});
express.js api:
const router = require('express').Router({ mergeParams: true });
import config from 'config';
import proxy from 'express-request-proxy';
router.get('', (...args) => {
let query = {};
if (config.FOO === 'bar') {
query.baz = true;
}
return proxy({
url: '/stuff',
query,
})(...args);
});
如果你想在测试用例的函数范围内安排模拟,你不能使用jest.mock(moduleName, factory, options) in a function scope, it should be used in the module scope. You should use jest.doMock(moduleName, factory, options)。
我们还需要在执行每个测试用例之前使用jest.resetModules()到
reset the module registry - the cache of all required modules.
这意味着您的 ./config
模块注册表将被重置,因此当您在 jest.doMock('./config', () => {...})
语句之后需要它时,它会为每个测试用例 return 不同的模拟值。
{ virtual: true }
选项意味着我没有安装 express-request-proxy
包,因此它不存在于我的 npm_modules
目录中。如果你已经安装了它,你可以去掉这个选项。
这是单元测试解决方案:
index.js
:
const router = require('express').Router({ mergeParams: true });
import config from './config';
import proxy from 'express-request-proxy';
router.get('', (...args) => {
console.log(config);
let query = {};
if (config.FOO === 'bar') {
query.baz = true;
}
return proxy({ url: '/stuff', query })(...args);
});
export default router;
config.js
:
export default {
FOO: '',
};
index.test.js
:
import request from 'supertest';
jest.mock('express-request-proxy', () => (data) => (req, res, next) => res.json(data), { virtual: true });
beforeEach(() => {
jest.resetAllMocks();
jest.resetModules();
});
describe('GET /', () => {
it('should get all stuff', () => {
jest.doMock('./config', () => ({}));
const router = require('./index').default;
const app = require('express')();
app.use(router);
return request(app)
.get('')
.expect(200)
.expect('Content-Type', /json/)
.then((response) => {
expect(response.body).toMatchSnapshot();
});
});
it('should get all stuff when FOO=bar', async () => {
jest.doMock('./config', () => ({
default: {
FOO: 'bar',
get: (key) => key,
},
__esModule: true,
}));
const router = require('./index').default;
const app = require('express')();
app.use(router);
await request(app)
.get('')
.expect(200)
.expect('Content-Type', /json/)
.then((response) => {
expect(response.body.query).toHaveProperty('baz');
});
});
});
100% 覆盖率报告的单元测试结果:
PASS Whosebug/61828748/index.test.js (11.966s)
GET /
✓ should get all stuff (8710ms)
✓ should get all stuff when FOO=bar (24ms)
console.log
{}
at Whosebug/61828748/index.js:7:11
console.log
{ FOO: 'bar', get: [Function: get] }
at Whosebug/61828748/index.js:7:11
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
index.js | 100 | 100 | 100 | 100 |
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 1 passed, 1 total
Time: 13.268s
index.test.js.snap
:
// Jest Snapshot v1
exports[`GET / should get all stuff 1`] = `
Object {
"query": Object {},
"url": "/stuff",
}
`;
源代码:https://github.com/mrdulin/react-apollo-graphql-starter-kit/tree/master/Whosebug/61828748
在 supertest 使用一次依赖项后,我无法重置依赖项的笑话模拟。感谢任何帮助或提示。
以下是我的api超测测试:
import request from 'supertest';
import router from '../index';
const app = require('express')();
app.use(router);
jest.mock('config', () => ({}));
jest.mock('express-request-proxy', () => data => (req, res, next) =>
res.json(data),
);
beforeEach(() => {
jest.resetAllMocks();
});
describe('GET /', () => {
it('should get all stuff', () =>
request(app)
.get('')
.expect(200)
.expect('Content-Type', /json/)
.then(response => {
expect(response.body).toMatchSnapshot(); // all good here
}));
it('should get all stuff when FOO=bar', async () => {
jest.mock('config', () => ({
FOO: 'bar',
get: key => key,
}));
// >> HERE <<
// config.FOO is still undefined!
// reseting mocks did not work ...
await request(app)
.get('')
.expect(200)
.expect('Content-Type', /json/)
.then(response => {
expect(response.body.query).toHaveProperty('baz'); // test fails ...
});
});
});
express.js api:
const router = require('express').Router({ mergeParams: true });
import config from 'config';
import proxy from 'express-request-proxy';
router.get('', (...args) => {
let query = {};
if (config.FOO === 'bar') {
query.baz = true;
}
return proxy({
url: '/stuff',
query,
})(...args);
});
如果你想在测试用例的函数范围内安排模拟,你不能使用jest.mock(moduleName, factory, options) in a function scope, it should be used in the module scope. You should use jest.doMock(moduleName, factory, options)。
我们还需要在执行每个测试用例之前使用jest.resetModules()到
reset the module registry - the cache of all required modules.
这意味着您的 ./config
模块注册表将被重置,因此当您在 jest.doMock('./config', () => {...})
语句之后需要它时,它会为每个测试用例 return 不同的模拟值。
{ virtual: true }
选项意味着我没有安装 express-request-proxy
包,因此它不存在于我的 npm_modules
目录中。如果你已经安装了它,你可以去掉这个选项。
这是单元测试解决方案:
index.js
:
const router = require('express').Router({ mergeParams: true });
import config from './config';
import proxy from 'express-request-proxy';
router.get('', (...args) => {
console.log(config);
let query = {};
if (config.FOO === 'bar') {
query.baz = true;
}
return proxy({ url: '/stuff', query })(...args);
});
export default router;
config.js
:
export default {
FOO: '',
};
index.test.js
:
import request from 'supertest';
jest.mock('express-request-proxy', () => (data) => (req, res, next) => res.json(data), { virtual: true });
beforeEach(() => {
jest.resetAllMocks();
jest.resetModules();
});
describe('GET /', () => {
it('should get all stuff', () => {
jest.doMock('./config', () => ({}));
const router = require('./index').default;
const app = require('express')();
app.use(router);
return request(app)
.get('')
.expect(200)
.expect('Content-Type', /json/)
.then((response) => {
expect(response.body).toMatchSnapshot();
});
});
it('should get all stuff when FOO=bar', async () => {
jest.doMock('./config', () => ({
default: {
FOO: 'bar',
get: (key) => key,
},
__esModule: true,
}));
const router = require('./index').default;
const app = require('express')();
app.use(router);
await request(app)
.get('')
.expect(200)
.expect('Content-Type', /json/)
.then((response) => {
expect(response.body.query).toHaveProperty('baz');
});
});
});
100% 覆盖率报告的单元测试结果:
PASS Whosebug/61828748/index.test.js (11.966s)
GET /
✓ should get all stuff (8710ms)
✓ should get all stuff when FOO=bar (24ms)
console.log
{}
at Whosebug/61828748/index.js:7:11
console.log
{ FOO: 'bar', get: [Function: get] }
at Whosebug/61828748/index.js:7:11
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
index.js | 100 | 100 | 100 | 100 |
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 1 passed, 1 total
Time: 13.268s
index.test.js.snap
:
// Jest Snapshot v1
exports[`GET / should get all stuff 1`] = `
Object {
"query": Object {},
"url": "/stuff",
}
`;
源代码:https://github.com/mrdulin/react-apollo-graphql-starter-kit/tree/master/Whosebug/61828748