【问题标题】:How to write unit tests for sequelize models with Chai如何使用 Chai 为 Sequelize 模型编写单元测试
【发布时间】:2018-03-05 01:43:30
【问题描述】:

我的测试正在运行并通过,但是 chai 的 done 功能搞砸了。我尝试了几种不同的方法,但我不明白在这些单元测试中我哪里出错了。我对单元测试和 chai 非常陌生,因此将不胜感激任何帮助

测试失败的地方:第40行(创建),第98行(更新)

有什么想法吗?

const chai = require('chai')
let should = chai.should()
let expect = chai.expect
let db = require('../app/models')
db.hosts.modelName = 'Hosts'
db.victims.modelName = 'Victims'
let models = [db.hosts, db.victims]

models.forEach(model => {
    describe(`${model.modelName} Model`, function (done) {
        var modelData = {
            guest_count: 3,
            start_date: "2018-01-11T00:00:00.000Z",
            end_date: "2018-01-12T00:00:00.000Z",
            location: {
                type: "Point",
                coordinates: [
                    -74.323564,
                    40.232323
                ]
            },
            first_name: "Sean",
            last_name: "Destroyed",
            phone: "7325556677",
            address: "123 main street, red bank, nj",
            email: "test@gmail.com",
        }

        it(`should create a new ${model.modelName}`, function () {

            model.create(modelData).then(function (user) {
                //victim name should be equivalent to the fake submission we are using
                expect(user.first_name).to.equal("Sean"); 
                //remove the entry from the database
                model.destroy({
                    where: {
                        id: user.id
                    }
                })
                done()
            })


        });

        it(`should delete a ${model.modelName} from the database`, function () {
            model.create(modelData).then(function (user) {
                //victim name should be equivalent to the fake submission we are using
                //remove the entry from the database
                model.destroy({
                    where: {
                        id: user.id
                    }
                })

                try {
                    model.findOne({
                        where: {
                            id: user.id
                        }
                    })
                } catch (err) {
                    expect(user.first_name).to.undefined; 
                    if (err) {
                        done()
                    }
                }

            })
        })

          it(`should update the ${model.modelName} entry in the database`, function () {
            model.create(modelData).then(function (user) {
                //after user is created, then update a value
                modelData.guest_count = 12

                model.update(modelData, {
                    where: {
                        id: user.id
                    }
                }).then(function(data) {
                    model.findOne({
                        where: {
                            id: user.id
                        }
                    }).then(function (data) {
                        expect(data.guest_count).to.equal(12);
                    }).then(function () {
                        model.destroy({
                            where: {
                                id: user.id
                            }
                        })
                    }).then(function() {
                        done()
                    })
                })

            })
        })
    })    
});

【问题讨论】:

    标签: node.js sequelize.js chai


    【解决方案1】:

    有两点需要牢记:

    (1) Sequelize 在其 ORM 方法中使用 Promise。因此,即使在您调用destroy 之后,您也需要附加一个回调,例如:

    model.destroy({
      where: {
          id: user.id
      }
    })
    .then(function() {
      // now do something
    });
    

    (2) chai 中的done 方法应该附加到每个测试,而不是测试块:

    describe('some test block', function() {
      it('should do something,' function(done) {
        User.findAll().then(function(users) {
          // expect users to do something
          done(); // tests are done
        });
      });
    });
    

    就您而言,这是两个失败的测试用例:

    // ensure "destroy" has a callback
    it(`should create a new ${model.modelName}`, function (done) {
        model.create(modelData).then(function (user) {
            //victim name should be equivalent to the fake submission we are using
            expect(user.first_name).to.equal("Sean"); 
            //remove the entry from the database
            model.destroy({
                where: {
                    id: user.id
                }
            }).then(function() {
              done();
            })  
        })
    });
    
    // update
    it(`should update the ${model.modelName} entry in the database`, function () {
      model.create(modelData).then(function (user) {
          //after user is created, then update a value
          modelData.guest_count = 12
    
          model.update(modelData, {
              where: {
                  id: user.id
              }
          }).then(function(data) {
              model.findOne({
                  where: {
                      id: user.id
                  }
              }).then(function (data) {
                  expect(data.guest_count).to.equal(12);
              }).then(function () {
                  model.destroy({
                      where: {
                          id: user.id
                      }
                  }).then(function() {
                      done()
                  })
              })
          })
      })
    })
    

    【讨论】:

    • 谢谢,这很有意义。你真的把我理解中的空白联系起来了。我仍然看到我的更新测试错误 done 不是一个函数。你建议我做什么?
    • (1) 是否安装了 mocha (mochajs.org)?这是 Chai 的首选测试运行器。安装它,然后运行 ​​mocha ./path-to-test.js` (2) 确保 done 仅在您的单个单元测试中作为参数传递:it('should...', function(done) {})
    【解决方案2】:

    @mcranston18 留下了一个非常详细的已接受答案。

    我想为其他找到问题的人或将来为 OP 添加的是async/await 的使用:

    describe('some test block', function() {
      it('should do something', async function() { // notice async and no done
        const users = await User.findAll()
        // expect users.to (...)
      })
    })
    

    这是一个非常简单的创建然后使用async/await更新的方法:

    describe('some test block', function () {
      it('should do something', async function () {
        const Joe = await User.create({ name: 'Jo' })  // oops
        // assertions/expect/should
        // ex: expect(Joe.name).to.equal('Jo')
    
        await Joe.update({ name: 'Joe' }) // that's better
        // assertions/expect/should
        // ex: expect(Joe.name).to.equal('Joe')
      })
    })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-24
      • 2019-12-22
      • 2019-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-30
      相关资源
      最近更新 更多