supertest使用它一次后,我无法重置依赖的笑话模拟。感谢您的帮助或提示。
以下是我的具有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),应在模块范围内使用它。如果要在测试用例的功能范围内安排模拟,则应使用jest.doMock(moduleName, factory, options)。
我们还需要在执行每个测试用例之前使用jest.resetModules() >>
重置模块注册表-所有必需模块的缓存。
这意味着您的
./config
模块注册表将被重置,以便在jest.doMock('./config', () => {...})
语句后需要时,它将为每个测试用例返回不同的模拟值。
{ 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 stackoverflow/61828748/index.test.js (11.966s) GET / ✓ should get all stuff (8710ms) ✓ should get all stuff when FOO=bar (24ms) console.log {} at stackoverflow/61828748/index.js:7:11 console.log { FOO: 'bar', get: [Function: get] } at stackoverflow/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/stackoverflow/61828748