javascript - 如何使用 Sinon.JS 存根承诺的方法?
问题描述
给定以下代码:(请注意,访问已被承诺)
const fs = require('fs')
const util = require('util')
const access = util.promisify(fs.access)
const custom = () => {
return access('myfile', fs.constants.R_OK)
.then(() => {
return true
}).catch(err => {
if (err.code !== 'ENOENT') throw err
return false
}).then(fileExists => {
return `File exists: ${fileExists}`
})
}
module.exports = custom
我的单元测试不起作用,因为access
调用的是真正的方法而不是存根方法:
const chai = require('chai')
const chaiAsPromised = require('chai-as-promised')
const custom = require('./custom')
const fs = require('fs')
const sinon = require('sinon')
chai.use(chaiAsPromised)
const expect = chai.expect
describe('custom', () => {
let sandbox = sinon.createSandbox()
afterEach(function () {
sandbox.restore()
})
it('should return file exists true', () => {
sandbox.stub(fs, 'access').yields(null)
return expect(custom()).to.eventually.equal('File exists: true')
})
it('should return file exists false', () => {
const error = new Error('No such file or directory')
error.code = 'ENOENT'
sandbox.stub(fs, 'access').yields(error)
return expect(custom()).to.eventually.equal('File exists: false')
})
})
如何使测试有效,文件access
中承诺了给定custom.js
?
参考:
解决方案
更新 问题已更新。回答底部的原始问题
您正在寻找的是Proxyquire。问题是它custom.js
需要它自己的fs
,并且您正在测试文件中存根fs
。Proxyquire
将需要一个文件,并替换该文件所需的任何文件/功能。
在你的例子中,它会是这样的。(运行它mocha <test file path>
)
测试文件:
const chai = require('chai');
const chaiAsPromised = require('chai-as-promised');
const proxyquire = require('proxyquire');
chai.use(chaiAsPromised);
const expect = chai.expect;
describe('custom', () => {
let custom;
const stubs = {
fs: {
accessAsync: () => {
// Since you mentioned that fs was promisified, we will
// make this a promise as well.
return Promise.resolve();
}
},
bluebird: {
// Stop bluebird from promisifying, since we handle it above.
promisifyAll: (req => req),
}
};
before(async function () {
custom = proxyquire('./custom', stubs);
});
it('should return file exists true', () => {
return expect(custom()).to.eventually.equal('File exists: true');
});
});
自定义.js
'use strict';
const bluebird = require('bluebird');
const fs = bluebird.promisifyAll(require('fs'));
module.exports = async function() {
let exists = true;
await fs.accessAsync('nonimportant.path', fs.constants.F_OK)
.catch( () => { exists = false; });
return `File exists: ${exists}`;
};
原始答案
在这种情况下不需要使用蓝鸟,诗浓可以处理。
您需要使用sinon.stub()函数。可以这样做:
const chai = require('chai');
const chaiAsPromised = require('chai-as-promised');
const sinon = require('sinon');
const fs = require('fs');
chai.use(chaiAsPromised);
const expect = chai.expect;
describe('fs.stat', function(){
before(function() {
sinon.stub(fs, 'stat').resolves('Your desired value');
});
it('should should be called', function(done){
expect(fs.stat('./some.file'))
.to.eventually.equal('Your desired value')
.notify(done);
});
});
推荐阅读
- swift - 列表未在 DestinationView 中传播更新
- elixir - 将字符串与 Elixir 列表中的随机值进行比较的问题
- javascript - 使用 discord Oauth2 时,如何在我的网站上显示用户名和头像?
- kml - 为什么这个 KmlLayer 示例不能在我的服务器上运行?
- view - .net core mvc:在区域上添加具有 crud 功能的控制器未正确生成代码和链接
- r - 为多个图像对象泛化 magick::image_apend
- javascript - 使用 e.target 时,未定义不是对象
- python - 如何使用 groupby() 函数在 Python 中制作宿舍?
- ruby - 关于在 Ruby 中实现游戏图形的新手问题
- heroku - 如何在heroku中添加Mozilla firefox