简体   繁体   English

如何存根Node.js MongoDB链式fn调用来模拟最终结果?

[英]How can I stub a Node.js MongoDB chained fn call to mock my end result?

I am trying to test (with Sinon.JS Stubs ) the following call with the Node.js MongoDB driver ... 我试图使用Node.js MongoDB驱动程序测试(使用Sinon.JS Stubs )以下调用...

collection.find({mood: 'happy'}).toArray((err, result) => {

  // array result

  cb(null, result);
});

What is hanging me up here is the .toArray() chained function. 让我挂在这里的是.toArray() 链接函数。 The above call returns result as the expected Array . 上面的调用将result作为预期的Array返回。


To demonstrate my struggle - and to contrast - I am able to stub the following call which is not chained as such... 为了展示我的努力-并进行对比-我可以对以下链接的呼叫进行存根...

collection.findOne({id: 'id'}, (err, result) => {

    // single result

    cb(null, result);
  });

stubb'd => 存根=>

findOneStub.yields(null, {username: 'craig'});

Is there a straightforward way to stub my .find call, which returns a function with .toArray on it to finally mock my results? 是否有一种简单的方法来存根.find调用,该调用将返回带有.toArray的函数以最终模拟我的结果?

What I usually do when I want to stub methods of complex nested object like with the Mongo driver case, is to mock an object that mimics the call chain like so: 当我想像Mongo驱动程序案例那样对复杂的嵌套对象的方法进行存根时,通常要做的是模拟一个模仿调用链的对象,如下所示:

Stubbing toArray() using callback 使用回调对toArray()进行存根

let mockDbCollection = {
  find: function() {
    return {
      toArray: function(cb) {
        const results = [{
          username: 'craig'
        }];

        cb(null, results);
      }
    };
  }
};

sinon.stub(db, 'collection')
  .returns(mockDbCollection);

db.collection('users').find({
  id: 'id'
}).toArray((err, docs) => {
  console.log(docs);
  done();

});

Stubbing toArray() using promise 使用promise存根toArray()

let mockDbCollection = {
  find: function() {
    return {
      toArray: function() {
        return Promise.resolve([{
          username: 'craig'
        }]);
      }
    };
  }
};

sinon.stub(db, 'collection')
  .returns(mockDbCollection);

db.collection('messages').find({
  id: 'id'
}).toArray().then((docs) => {
  console.log(docs);
  done();
});

This paradigm can be used in any case that you want to mock a sequence of calls on a complex object, focusing only on the response of the last call in the chain. 在您要模拟复杂对象上的一系列调用的任何情况下,都可以使用此范例,仅关注链中最后一个调用的响应。 You can go as deep as you want without any issues. 您可以根据需要进行任意操作,没有任何问题。

If you want something more advanced like setting behavior of the stub or counting calls, etc you can find out some other techniques in this article . 如果您想要更高级的功能,例如设置存根的行为或计数呼叫等,则可以在本文中找到其他一些技巧。 The author showcases some examples using complex DOM objects. 作者展示了一些使用复杂DOM对象的示例。

Adapting the technique from the tutorial in our example, we could easily do the following: 在我们的示例中改编本教程中的技术,我们可以轻松地执行以下操作:

// here we stub the db.collection().findOne() method
// and fabricate a response
let stubFindOne = this.sandbox.stub().resolves({
  _id: 'id'
});

// now, we can set the stub 
// function in our mock object
let mockDb = {
  collection: () => {
    return {
      findOne: stubFindOne
    };
  }
};

This way, we can manipulate and inspect the stubbed method as we would normally do, eg 这样,我们可以像往常一样操作和检查存根方法,例如

const args = stubFindOne.firstCall.args;

would return the arguments list of the first call, etc. 将返回第一个调用的参数列表,依此类推。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM