****编辑:**用一个简单的例子重写,首先:
我有一个测试文件和两个模块。moduleA
具有相关性moduleB
// moduleA.js
const ModuleB = require('./moduleB');
function functionA() {
return 20 + ModuleB.functionB();
};
module.exports = { functionA };
// moduleB.js
const functionB = () => {
return 10;
}
module.exports = { functionB }
我的测试文件使用proxyquire存根出functionB
(从moduleB
返回):
const sinon = require('sinon');
const proxyquire = require('proxyquire');
describe('Unit Tests', function() {
it('should work', () => {
const mockedFn = sinon.stub();
mockedFn.returns(30);
const copyModuleA = proxyquire('./moduleA', {
'./moduleB': {
functionB: mockedFn
}
});
console.log(copyModuleA.functionA());
})
});
因此它输出50
(存根函数B 30
+函数A 20
)
现在我尝试将这个例子应用到我的代码中:
moduleA在这里是一个名为validation.js
的文件,它依赖于moduleB,在这里是一个sequelize模型Person
,它有我想要模拟的函数:findOne
validation.js
导出module.exports = { validateLogin };
,这是一个调用validate
的函数,validate
返回使用Person.findOne()
的函数
所以在我看来,就像这个简单的例子一样,我需要创建一个存根,指向proxyquire
中的验证模块,并引用依赖项及其findOne
函数,如下所示:
const stubbedFindOne = sinon.stub();
stubbedFindOne.resolves();
validationModule = proxyquire('../../utils/validation', {
'../models/Person': {
findOne: stubbedFindOne
}
});
这个 * 应该 * 在validation.js
中stub Person.findOne
。但是看起来没有。我不知道为什么。
let validationModule;
describe('Unit Tests', () => {
before(() => {
const stubbedFindOne = sinon.stub();
stubbedFindOne.resolves();
validationModule = proxyquire('../../utils/validation', {
'../models/Person': {
findOne: stubbedFindOne
}
});
})
it.only('should return 422 if custom email validation fails', async() => {
const wrongEmailReq = { body: {email: 'nik@hotmail.com'} };
const res = {
statusCode: 500,
status: (code) => {this.statusCode = code; return this},
};
const validationFn = validationModule.validateLogin();
const wrongEmail = await validationFn(wrongEmailReq, res, ()=>{});
expect(wrongEmail.errors[0].msg).to.be.equal('Custom Authorisation Error');
return;
})
这是我的validation.js
文件:
const Person = require('../models/Person');
// parallel processing
const validate = validations => {
return async (req, res, next) => {
await Promise.all(validations.map(validation => validation.run(req)));
const errors = validationResult(req);
if (errors.isEmpty()) {
return next();
}
const error = new Error();
error.message = process.env.NODE_ENV === 'development'? 'Validation Failed':'Error';
error.statusCode = !errors.isEmpty()? 422:500;
error.errors = errors.array({onlyFirstError: true});
next(error);
return error;
};
};
const validateLogin = () => {
const validations = [
body('email')
.isString()
// snip
.custom(async (value, {req}) => {
try{
const person = await Person.findOne({ where: { email: value } });
if(!person) return Promise.reject('Custom Authorisation Error');
} catch(err) {
throw err;
}
})
.trim(),
];
return validate(validations);
}
module.exports = {
validateLogin
};
1条答案
按热度按时间5vf7fwbs1#
因此,除了我对函数的存根处理方式不同之外,小示例和我的应用程序中的代码都是正确的,它不应该是
resolve
或reject
(我绝望地尝试了这两种方法),它应该返回null
以满足条件,而不是跳转到catch块:希望这个简单的例子对其他使用proxyquire的人有所帮助