使用 sinon 和 mocha 执行测试时不执行存根函数
Stub function does not executed when executing test using sinon and mocha
我正在尝试模拟一个函数以通过使用 sinon
和 mocha
的测试。
app.js:
const express = require('express');
const { isValid } = require('./utils/index');
const config = require('./config.json')[process.env.NODE_ENV || 'development']
const app = express();
app.get('/', (req, res)=> {
const url = config.url;
try {
const validUrl = isValid(url)
.then(() => {
return res.redirect(`https://${url}`);
})
.catch(() => {
return res.status(400).send('Unable to redirect to the given url');
})
} catch(error) {
return res.send('Internal Server Error')
}
})
const port = process.env.port || 3000;
const server = app.listen(port, ()=> {
console.log('server listens on 127.0.0.1:3000');
})
module.exports = {server, app};
config.json:
{
"development": {
"url": "www.whosebug.com"
},
"test": {
"url": "www.whosebug.com"
}
}
utils/index.js:
const http = require('http');
module.exports.isValid = (url) => {
const options = {
method: 'HEAD',
host: url
}
const promise = new Promise((resolve, reject) => {
const req = http.request(options, () => {
return resolve(true)
})
req.on('error', () => {
return reject(new Error('Not valid'))
})
req.end();
})
return promise;
}
test/index.js:
const request = require('supertest');
const chai = require('chai');
const sinon = require('sinon');
const index = require('../utils/index')
const { expect } = chai;
const { server } = require('../app');
const {url} = require('../config.json')['test'];
describe('isValid Test', () => {
it('Should redirects an error when the url is not valid', async() => {
const stub = sinon.stub(index, 'isValid');
stub.withArgs(url).returns(Promise.reject(new Error('Not Valid')));
const { status } = await request(server).get('/');
expect(status).to.equal(400);
})
})
当我执行测试时,我得到了这个错误:
(node:23622) UnhandledPromiseRejectionWarning: Error: Not Valid
at Context.it (/home/hs/perso/mockTests/chaiMock/test/index.js:17:52)
at callFn (/home/hs/perso/mockTests/chaiMock/node_modules/mocha/lib/runnable.js:387:21)
at Test.Runnable.run (/home/hs/perso/mockTests/chaiMock/node_modules/mocha/lib/runnable.js:379:7)
at Runner.runTest (/home/hs/perso/mockTests/chaiMock/node_modules/mocha/lib/runner.js:535:10)
at /home/hs/perso/mockTests/chaiMock/node_modules/mocha/lib/runner.js:653:12
at next (/home/hs/perso/mockTests/chaiMock/node_modules/mocha/lib/runner.js:447:14)
at /home/hs/perso/mockTests/chaiMock/node_modules/mocha/lib/runner.js:457:7
at next (/home/hs/perso/mockTests/chaiMock/node_modules/mocha/lib/runner.js:362:14)
at Immediate.<anonymous> (/home/hs/perso/mockTests/chaiMock/node_modules/mocha/lib/runner.js:425:5)
at runCallback (timers.js:705:18)
at tryOnImmediate (timers.js:676:5)
at processImmediate (timers.js:658:5)
(node:23622) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:23622) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
url: www.whosebug.com
1) Should redirects an error when the url is not valid
0 passing (122ms)
1 failing
1) isValid Test
Should redirects an error when the url is not valid:
AssertionError: expected 302 to equal 400
+ expected - actual
-302
+400
at Context.it (test/index.js:22:27)
at process._tickCallback (internal/process/next_tick.js:68:7)
尝试检查根据您的请求在 "host" 发送的值,我相信您正在点击 "www.whosebug.com" 并获得 http 代码 400,这就是您在测试中遇到错误的原因
这里的问题是你的应用程序模块是必需的,然后在 sinon 存根你感兴趣的函数之前拉入 utils/index 文件,我相信模块加载器然后缓存它所以 sinon 试图存根它没有效果。
要看到您的测试成功通过,您需要在 require 应用程序之前对 isValid 函数进行存根,即
const request = require('supertest');
const chai = require('chai');
const sinon = require('sinon');
const { expect } = chai;
const index = require('../utils/index');
/* Stub here before the server is required */
const stub = sinon.stub(index, 'isValid');
const { server } = require('../app');
const { url } = require('../config.json')['test'];
describe('isValid Test', () => {
it('Should redirects an error when the url is not valid', async () => {
stub.withArgs(url).rejects('Not Valid');
const { status } = await request(server).get('/');
expect(status).to.equal(400);
});
});
此外,要在测试时停止看到未处理的承诺拒绝 运行,您可以使用 .rejects()
function 而不是创建自己的拒绝承诺。
我正在尝试模拟一个函数以通过使用 sinon
和 mocha
的测试。
app.js:
const express = require('express');
const { isValid } = require('./utils/index');
const config = require('./config.json')[process.env.NODE_ENV || 'development']
const app = express();
app.get('/', (req, res)=> {
const url = config.url;
try {
const validUrl = isValid(url)
.then(() => {
return res.redirect(`https://${url}`);
})
.catch(() => {
return res.status(400).send('Unable to redirect to the given url');
})
} catch(error) {
return res.send('Internal Server Error')
}
})
const port = process.env.port || 3000;
const server = app.listen(port, ()=> {
console.log('server listens on 127.0.0.1:3000');
})
module.exports = {server, app};
config.json:
{
"development": {
"url": "www.whosebug.com"
},
"test": {
"url": "www.whosebug.com"
}
}
utils/index.js:
const http = require('http');
module.exports.isValid = (url) => {
const options = {
method: 'HEAD',
host: url
}
const promise = new Promise((resolve, reject) => {
const req = http.request(options, () => {
return resolve(true)
})
req.on('error', () => {
return reject(new Error('Not valid'))
})
req.end();
})
return promise;
}
test/index.js:
const request = require('supertest');
const chai = require('chai');
const sinon = require('sinon');
const index = require('../utils/index')
const { expect } = chai;
const { server } = require('../app');
const {url} = require('../config.json')['test'];
describe('isValid Test', () => {
it('Should redirects an error when the url is not valid', async() => {
const stub = sinon.stub(index, 'isValid');
stub.withArgs(url).returns(Promise.reject(new Error('Not Valid')));
const { status } = await request(server).get('/');
expect(status).to.equal(400);
})
})
当我执行测试时,我得到了这个错误:
(node:23622) UnhandledPromiseRejectionWarning: Error: Not Valid
at Context.it (/home/hs/perso/mockTests/chaiMock/test/index.js:17:52)
at callFn (/home/hs/perso/mockTests/chaiMock/node_modules/mocha/lib/runnable.js:387:21)
at Test.Runnable.run (/home/hs/perso/mockTests/chaiMock/node_modules/mocha/lib/runnable.js:379:7)
at Runner.runTest (/home/hs/perso/mockTests/chaiMock/node_modules/mocha/lib/runner.js:535:10)
at /home/hs/perso/mockTests/chaiMock/node_modules/mocha/lib/runner.js:653:12
at next (/home/hs/perso/mockTests/chaiMock/node_modules/mocha/lib/runner.js:447:14)
at /home/hs/perso/mockTests/chaiMock/node_modules/mocha/lib/runner.js:457:7
at next (/home/hs/perso/mockTests/chaiMock/node_modules/mocha/lib/runner.js:362:14)
at Immediate.<anonymous> (/home/hs/perso/mockTests/chaiMock/node_modules/mocha/lib/runner.js:425:5)
at runCallback (timers.js:705:18)
at tryOnImmediate (timers.js:676:5)
at processImmediate (timers.js:658:5)
(node:23622) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:23622) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
url: www.whosebug.com
1) Should redirects an error when the url is not valid
0 passing (122ms)
1 failing
1) isValid Test
Should redirects an error when the url is not valid:
AssertionError: expected 302 to equal 400
+ expected - actual
-302
+400
at Context.it (test/index.js:22:27)
at process._tickCallback (internal/process/next_tick.js:68:7)
尝试检查根据您的请求在 "host" 发送的值,我相信您正在点击 "www.whosebug.com" 并获得 http 代码 400,这就是您在测试中遇到错误的原因
这里的问题是你的应用程序模块是必需的,然后在 sinon 存根你感兴趣的函数之前拉入 utils/index 文件,我相信模块加载器然后缓存它所以 sinon 试图存根它没有效果。
要看到您的测试成功通过,您需要在 require 应用程序之前对 isValid 函数进行存根,即
const request = require('supertest');
const chai = require('chai');
const sinon = require('sinon');
const { expect } = chai;
const index = require('../utils/index');
/* Stub here before the server is required */
const stub = sinon.stub(index, 'isValid');
const { server } = require('../app');
const { url } = require('../config.json')['test'];
describe('isValid Test', () => {
it('Should redirects an error when the url is not valid', async () => {
stub.withArgs(url).rejects('Not Valid');
const { status } = await request(server).get('/');
expect(status).to.equal(400);
});
});
此外,要在测试时停止看到未处理的承诺拒绝 运行,您可以使用 .rejects()
function 而不是创建自己的拒绝承诺。