我试图对箭头函数removeUserEntry
进行存根,但是在测试中执行acctRmRouter
时,我的存根似乎被忽略了。我必须明确地将UserModel
的{{1}}方法存根才能成功进行测试,我想知道为什么会出现无知,谢谢
acctRoute.js
deleteOne
acctRoute.spec.js
const removeUserEntry = (username) => {
const condition = {username: username};
return UserModel.deleteOne(condition)
.then((res) => {
if (res.n < 1) {
throw new Error('User not exists');
}
return true;
}, (err) => {throw err})
.catch(err => err);
};
const acctRmRouter = function(httpReq, httpRes, next) {
if (!argValidate(httpReq.body, 'string')) {
httpRes.locals = {api: { success: false }};
// return to avoid running downwards
return next(new Error('bad argument'));
}
// perform DB rm user
return removeUserEntry(httpReq.body).then((res) => {
if (res === true) {
httpRes.locals = {api: { success: true }};
next();
} else {
httpRes.locals = {api: { success: false }}
next(res);
}
});
};
以下内容确实以类似于it('should remove user handler pass success request', async () => {
shouldDbReset = false;
const mockRequestURL = "/api/account/rm-user";
const mockRequest = httpMocks.createRequest({
method: "POST",
url: mockRequestURL,
headers: {
"Content-Type": "text/plain"
},
body: 'validRmUser',
});
const mockResponse = httpMocks.createResponse();
const spyNext = sinon.spy();
const stubRemoveUserEntry = sinon.stub(accountRouterHelper, 'removeUserEntry');
stubRemoveUserEntry.callsFake(function(){
return Promise.resolve(true);
}); // Expecting this function to be stubbed, and always return true
await accountRouterHelper.acctRmRouter(mockRequest, mockResponse, spyNext);
/* But when running the function, it returns error object with "User not exists"
which is not what intended */
const firstCallArgs = spyNext.getCall(0).args[0];
expect(spyNext.called).to.be.true;
console.log(`firstCallArgs: ${firstCallArgs}`)
expect(firstCallArgs instanceof Error).to.be.false;
expect(spyNext.args[0].length).to.equal(0);
expect(mockResponse.statusCode).to.equal(200);
expect(mockResponse.locals.api.success).to.be.true;
stubRemoveUserEntry.resetHistory();
stubRemoveUserEntry.restore();
});
的模式成功存根。
acctRoute.js
removeUserEntry
acctRoute.spec.js
const createUserEntry = (userData) => {
const updatedUserData = filterInput(userData);
const userDoc = new UserModel(updatedUserData);
return userDoc.save()
.then((userObj) => userObj._doc
,(err) => { throw err;})
.catch(err => err);
};
const acctCreateRouter = function (httpReq, httpRes, next) {
// do something in mongodb
return createUserEntry(userCondition)
.then((response) => {
if (!(response instanceof Error)) {
httpRes.locals = {api: { success: true}};
next();
} else {
httpRes.locals = {api: { success: false}};
next(response);
}
}, (err) => {
httpRes.locals = {api: { success: false}};
next(err);
})
.catch((err) => {
httpRes.locals = {api: { success: false}};
next(err);
});
};
const acctOutputRouter = function(req, res, next) {
if (res.locals) {
res.send(res.locals.api);
} else {next()}
};
答案 0 :(得分:0)
问题
sinon.stub(accountRouterHelper, 'removeUserEntry')
替换模块导出。
acctRmRouter()
不是调用模块导出,而是直接调用removeUserEntry()
,因此对模块导出进行存根操作无济于事。
解决方案
重构acctRmRouter()
以调用removeUserEntry()
的模块导出。
ES6
// import module into itself
import * as self from './acctRoute';
...
const acctRmRouter = function(httpReq, httpRes, next) {
...
// call the function using the module
return self.removeUserEntry(httpReq.body).then((res) => {
...
Node.js模块
...
const acctRmRouter = function(httpReq, httpRes, next) {
...
// call the function using module.exports
return module.exports.removeUserEntry(httpReq.body).then((res) => {
...