Jasmine spyOn mongoose save

时间:2014-12-29 05:14:37

标签: javascript mongoose jasmine

我想模拟Mongoose模型的save()函数。我要测试的函数在名为user.js的文件中看起来像这样:

var User = import('User.js')

post: function(req, res) {
  var user = new User({
      password    : req.body.password,
      email       : req.body.email,
  });
  user.save( function(err) {
    if (err) {
      ....
    } else {
      ....
    }
  });

我尝试在另一个名为user_spec.js的文件中编写一个看起来像这样的测试:

var Hander = require('user.js')

it('works properly', function() {
  spyOn(User, 'save').andReturn(null)
  Handler.post(req, res);
});

但这给了我错误:

save() method does not exist

我已经做了一些挖掘,看起来User模型本身没有save()方法,实例就是这样。这意味着我必须模拟User的构造函数,但是我遇到了很多麻烦。其他帖子引用如下声明:

spyOn(window, User)

要解决此问题,但在NodeJS中,全局(此处窗口等效),没有User,因为我导入是一个变量。是否有可能模拟构造函数给我一些模拟的save()?我还看了一个名为rewire的npm模块,但是我希望我能够在没有模拟和替换处理程序中的整个用户模块的情况下做到这一点。

3 个答案:

答案 0 :(得分:1)

这并不能解决模拟局部变量的问题,但它会解决单元测试新文档创建的问题。

创建新文档时,最好使用Model.create()。这可以有效地嘲笑,而且代码更少。处理这个并测试它的正确方法是:

var User = import('User.js')

post: function(req, res) {
  User.create({
      password    : req.body.password,
      email       : req.body.email,
  }, function(err) {
    if (err) {
      ....
    } else {
      ....
    }
  });
});

对应测试:

var Hander = require('user.js')

it('works properly', function() {
  spyOn(User, 'create').andReturn(null)
  Handler.post(req, res);
});

希望这种解决方法可以帮助其他人对茉莉花和猫鼬单位测试感到沮丧。

答案 1 :(得分:0)

创建对象后,您只能与间谍交换功能。因此,这将有效:

var user = new User(…);
spyOn(user, save).…;
doSomething();

这不会:

spyOn(User, save).…
doSomething()

当然你可以改变mongoose里面的函数来创建对象的保存功能......但是你可能不想去那里。

答案 2 :(得分:0)

在一个理智的世界里,你可以做到这一点。

spyOn(Model.prototype, 'save')

然而,Mongoose试图将所有Model函数重载为node.js同时回调和Promises。为此,他们在不阅读实际模型代码(https://github.com/Automattic/mongoose/blob/master/lib/model.js)的情况下以一种难以预测的方式操纵原型。

这是一个实际上对我有用的例子。

spyOn(Model.prototype, '$__save').and.callFake(function (options, callback) { callback(); });

为了记录,我在应用程序代码中使用带有Promise的Mongoose。