如何对猫鼬模型进行单元测试?

时间:2017-03-19 19:40:36

标签: node.js unit-testing mongoose sinon

所以我试着在一整天都找到这个。我找到了一些提示,但这还不够。

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

我的代码:

•控制器:

  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
  • 摩卡
  • 兴农
  • 兴农-猫鼬

1 个答案:

答案 0 :(得分:2)

Mockgoose运行MongoDB的内存副本,一旦设置,就会修补mongoose,以便你的app连接转到测试实例。

y

Mockgoose保存了所有"为什么我的模仿不像猫鼬"一旦你通过一个简单的例子进入多个查询或更复杂的操作,时间只会变得更糟。

虽然测试在这个阶段并不是真正的单元测试,但如果您可以使用before(function() { return mockgoose.prepareStorage().then(()=>{ return mongoose.connect('mongodb://127.0.0.1:27017/whatever') }) }) after(function() { return mockgoose.helper.reset() }} mongoose,那么它是我发现的用于猫鼬数据库交互的最佳解决方案。 mongodbmongodb-prebuilt到您的"单位"测试。

monbodb-prebuilt依赖关系大约为200MB,因此添加它会影响开发人员依赖安装时间。