茉莉花间谍猫鼬保存

Jasmine spyOn mongoose save

本文关键字:保存 间谍 茉莉花      更新时间:2023-09-26

>我想嘲笑猫鼬模型的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

我做了更多的挖掘,看起来用户模型本身没有 save() 方法,一个实例有。这意味着我必须嘲笑 User 的构造函数,但我在这方面遇到了很多麻烦。其他帖子引用如下声明:

spyOn(window, User)

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

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

创建新文档时,最好使用 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);
});

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

您只能在创建对象后与间谍交换函数。因此,这将起作用:

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

这不会:

spyOn(User, save).…
doSomething()

当然,您可以更改猫鼬内部在对象上创建保存函数的功能......但你可能不想去那里。

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

spyOn(Model.prototype, 'save')

但是,Mongoose 尝试重载它们的所有模型函数以同时用作节点.js回调和承诺。为此,他们以一种在不读取实际模型代码(https://github.com/Automattic/mongoose/blob/master/lib/model.js)的情况下难以预测的方式操纵原型。

这里有一个对我有用的例子。

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

作为记录,我在应用程序代码中使用带有承诺的猫鼬。