无法存根函数返回承诺

时间:2018-09-02 11:13:36

标签: javascript promise sinon stub

我试图对箭头函数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()}
};

1 个答案:

答案 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) => {

  ...