代码之家  ›  专栏  ›  技术社区  ›  Sean Kelly

如何使用Chai编写sequelize模型的单元测试

  •  1
  • Sean Kelly  · 技术社区  · 7 年前

    我的测试正在运行并通过,但chai的已完成功能正在出错。我尝试了几种不同的方法,但我不明白在这些单元测试中我会错在哪里。我对单元测试和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()
                        })
                    })
    
                })
            })
        })    
    });
    
    2 回复  |  直到 7 年前
        1
  •  4
  •   mcranston18    7 年前

    有两件事需要记住:

    (1) Sequelize为其ORM方法使用promises。所以,即使在你打电话之后 destroy ,您需要附加回调,例如:

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

    (2) The done 与试块相反,应在每个试验中附上chai中的方法:

    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()
                  })
              })
          })
      })
    })
    
        2
  •  3
  •   vapurrmaid    7 年前

    @麦克兰斯顿18给出了一个非常详细的公认答案。

    我想为其他发现问题的人或将来的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 (...)
      })
    })
    

    下面是一种非常简单的创建然后更新的方法 异步/等待 :

    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')
      })
    })
    
    推荐文章