node.js - 如何对 Mongoose 模型进行单元测试?

标签 node.js unit-testing mongoose sinon

所以我一整天都试图自己找出答案。我找到了一些提示,但这还不够。

我想进行查询并对其结果进行操作。问题是,我使用的库不允许这样做,因为它返回字符串或对象格式。它不模拟结果。或者至少我无法以这种方式实现它。

我的代码:

• Controller :

  const UserMock = sinon.mock(User)
  const expectedResult = {
      "_id" : "58cc67ab9b11ec4cfd9ebb6e",
      "email" : "test@email.com", 
      "password" : "$2a$10$3Oka.IuS/xoGJ4CgxWOPVerE.IVvKemsZchegvwsxopSwIJ08G1P."
    }

  UserMock
    .expects('findOne').withArgs({ email: 'test@email.com' })
    .chain('exec')
    .resolves(expectedResult)

  User.findByEmail('test@email.com')
    .then((user) => user.comparePassword('password'))
    .then((user) => user.publishParse(user))
    .then((user) =>
    {
      UserMock.verify()
      UserMock.restore()
      assert.equal(user, {expectedResult.email, id: expectedResult._id})
      done()
    })
    .then(console.log)
    .catch(console.log)

• 型号:

...

const userSchema = new Schema({
  email: {
    type: String,
    required: true,
    unique: true,
    dropDups: true,
    minlength: [5],
    validate: {
      isAsync: true,
      validator: isEmail,
      message: 'Invalid email'
    }
  },
  password: {
    type: String,
    required: true,
    minlength: [6, "Password must has at least 6 chars."]
  }
}, {
  toJSON: {
    transform: function(doc, ret)
    {
      ret.id = ret._id
      delete ret._id
      delete ret.__v
    }
  }
})

userSchema.methods.comparePassword = function(password)
{
  return new Promise((resolve, reject) =>
  {
    bcrypt.compare(password, this.password, (err, isMatch) =>
    {
      if (err || !isMatch)
      {
        return reject(err)
      }

      resolve(this)
    })
  })
}

userSchema.methods.publishParse = function()
{
  let _user = this.toJSON()
  delete _user.password
  return _user
}

userSchema.statics.findByEmail = function(email)
{
  return this.findOne({ email }).exec()
}

const User = mongoose.model('User', userSchema)
export default User

我使用的库:

  • Mongoose
  • 摩卡
  • 诗农
  • sinon- Mongoose

最佳答案

Mockgoose运行 MongoDB 的内存副本,安装完成后,修补 mongoose,以便您的应用程序连接进入测试实例。

before(function() {
  return mockgoose.prepareStorage().then(()=>{
    return mongoose.connect('mongodb://127.0.0.1:27017/whatever')
  })
})

after(function() {
  return mockgoose.helper.reset()
}}

Mockgoose 节省了所有“为什么我的模拟不像 Mongoose ”的时间,一旦您将一个简单的示例转变为多个查询或更复杂的操作,这种情况只会变得更糟。

虽然现阶段的测试并不是真正的单元测试,但如果您可以接受 mongoosemongodb< 的添加,那么它是我为 mongoose 数据库交互找到的最佳解决方案mongodb-prebuilt 到您的测试“单元”。

monbodb-prebuilt 依赖项约为 200MB,因此添加它可能会影响开发依赖项安装时间。

关于node.js - 如何对 Mongoose 模型进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42891321/

相关文章:

node.js - 服务器发送成功,即使没有找到任何东西

javascript - nodejs - 从子模块调用父模块内的函数

node.js - 如何使用 docker-compose.debug.yml 调试在 docker 中运行的 Node ?

node.js - mongoError : Topology was destroyed

php - 单元测试套件需要多少内存?

javascript - Mongoose 通过键获取最高值

javascript - 如何使用 Promise 查看 setTimeout 中错误的完整堆栈跟踪

ruby-on-rails - Rails - 使用开发数据填充测试数据库

java - 使用 Mockito 测试增强的 Java 行为

node.js - Mongoose 在保存之前更新模型