【问题标题】:How to unit test mongoose model?如何对猫鼬模型进行单元测试?
【发布时间】:2017-08-11 00:09:05
【问题描述】:

所以我一整天都在尝试自己找出这个问题。我找到了一些技巧,但这还不够。

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

我的代码:

• 控制器:

  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

我使用的库:

  • 猫鼬
  • 摩卡
  • 诗乃
  • sinon-猫鼬

【问题讨论】:

    标签: node.js unit-testing mongoose sinon


    【解决方案1】:

    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”的时间,只有当您通过一个简单的示例进入多个查询或更复杂的操作时,这种情况才会变得更糟。

    虽然在这个阶段测试并不是真正的单元测试,但如果你可以忍受在你的“单元”的测试。

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

    【讨论】:

      猜你喜欢
      • 2018-12-30
      • 2019-05-04
      • 2017-04-26
      • 2014-04-09
      • 1970-01-01
      • 2019-10-10
      • 2013-01-16
      • 2016-05-19
      • 2017-10-11
      相关资源
      最近更新 更多