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

时间:2022-08-24 21:51:25

So I tried to find this out on my own for the whole day. I've found some tips, but that's not enough.

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

I want make a query and manipulate with it's result. Problem is, the library I've used doesn't allow for that, as it returns a string, or object format. It doesn't simulate the result. Or at least I couldn't achieve it that way.

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

my code:

我的代码:

• 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)

• model:

•模型:

...

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

Libraries I used:

我使用库:

  • mongoose
  • 猫鼬
  • mocha
  • 摩卡
  • sinon
  • 西农
  • sinon-mongoose
  • sinon-mongoose

1 个解决方案

#1


2  

Mockgoose runs an in memory copy of MongoDB and once setup, patches mongoose so your app connections go to the test instance.

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 saves all the "why isn't my mock like mongoose" time which only gets worse once you get past a simple example into multiple queries or more complex operations.

Mockgoose省去了所有“为什么我的mock不像mongoose那样”的时间,只有当您通过一个简单的示例进入多个查询或更复杂的操作时,情况才会变得更糟。

Although the tests aren't really unit tests at this stage, it's the best solution I've found for mongoose database interaction if you can live with the addition of mongoose and mongodb and mongodb-prebuilt to your "unit" of test.

虽然这些测试在这个阶段并不是真正的单元测试,但是如果您能够接受在您的“测试单元”中添加mongoose、mongodb和mongodb,那么对于mongoose数据库交互来说,这是我找到的最好的解决方案。

The monbodb-prebuilt dependency is ~ 200MB so adding it can impact dev dependency install time.

monbo -prebuilt dependency大约为200MB,所以增加它会影响开发依赖安装时间。

#1


2  

Mockgoose runs an in memory copy of MongoDB and once setup, patches mongoose so your app connections go to the test instance.

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 saves all the "why isn't my mock like mongoose" time which only gets worse once you get past a simple example into multiple queries or more complex operations.

Mockgoose省去了所有“为什么我的mock不像mongoose那样”的时间,只有当您通过一个简单的示例进入多个查询或更复杂的操作时,情况才会变得更糟。

Although the tests aren't really unit tests at this stage, it's the best solution I've found for mongoose database interaction if you can live with the addition of mongoose and mongodb and mongodb-prebuilt to your "unit" of test.

虽然这些测试在这个阶段并不是真正的单元测试,但是如果您能够接受在您的“测试单元”中添加mongoose、mongodb和mongodb,那么对于mongoose数据库交互来说,这是我找到的最好的解决方案。

The monbodb-prebuilt dependency is ~ 200MB so adding it can impact dev dependency install time.

monbo -prebuilt dependency大约为200MB,所以增加它会影响开发依赖安装时间。