You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Chai编写Sequelize模型单元测试?done函数异常求助

Hey there! Let's work through this Chai + Sequelize unit testing issue you're hitting with the done() function in your create (line 40) and update (line 98) tests. Since you're new to both tools, I'll break down the most common fixes step by step.

First: Stop mixing async/await and done()

A super common gotcha is using both async on your test function and calling done() at the end. Test frameworks (like Mocha, which pairs with Chai) handle async tests two ways: either by using async/await (which returns a promise) or by calling done() to signal completion. Mixing them causes weird errors because the framework might get conflicting signals about when the test finishes.

Bad:

it('creates a user', async (done) => { // ❌ Mixes async and done
  const user = await User.create({ name: 'Test' });
  expect(user.name).to.equal('Test');
  done(); // This will cause an error!
});

Fix: Pick one approach:

  1. Use async/await (no done() needed):
it('creates a user', async () => {
  const user = await User.create({ name: 'Test' });
  expect(user.name).to.equal('Test');
});
  1. Use done() with promise .then()/.catch():
it('creates a user', (done) => {
  User.create({ name: 'Test' })
    .then(user => {
      expect(user.name).to.equal('Test');
      done(); // Signal success to the test framework
    })
    .catch(err => done(err)); // Pass errors to done so the test fails properly
});

Fixing your Create Test (Line 40)

If your create test is failing with a done() error, it’s likely because you’re not handling the promise correctly or forgetting to call done() in all paths.

Common issues to check:

  • Did you forget to call done() after your assertions?
  • Did you skip the .catch() block, so errors from Sequelize (like validation failures) never get passed to done()?
  • Are you trying to create a record that violates your model’s validations (e.g., missing a required field) but not checking for that error?

Example of a solid create test with async/await:

it('should create a valid user', async () => {
  // Arrange: Define your test data
  const testUserData = {
    email: 'test@example.com',
    password: 'secure123',
    name: 'Test User'
  };

  // Act: Create the user
  const user = await User.create(testUserData);

  // Assert: Verify the user was created correctly
  expect(user.email).to.equal(testUserData.email);
  expect(user.name).to.equal(testUserData.name);
  expect(user.id).to.exist; // Ensure an ID was generated
});

Fixing your Update Test (Line 98)

Sequelize’s update() method returns an array [numberOfAffectedRows, updatedInstances] (not a single instance), which trips up a lot of new users. If you’re trying to assert on the updated data directly from update(), you’ll run into issues.

Common fixes:

  1. Reload the instance after updating to get the fresh data from the database
  2. Query for the updated record using findByPk() or another query method

Example of a reliable update test:

it('should update a user\'s name', async () => {
  // Arrange: Create a user first
  const user = await User.create({ name: 'Old Name', email: 'update@example.com' });

  // Act: Update the user's name
  const [affectedRows] = await User.update(
    { name: 'New Name' },
    { where: { id: user.id } } // Target the correct user
  );

  // Assert 1: Verify one row was updated
  expect(affectedRows).to.equal(1);

  // Assert 2: Verify the name actually changed
  const updatedUser = await User.findByPk(user.id);
  expect(updatedUser.name).to.equal('New Name');
});

If you prefer using done() instead of async/await:

it('should update a user\'s name', (done) => {
  User.create({ name: 'Old Name', email: 'update@example.com' })
    .then(user => {
      return User.update(
        { name: 'New Name' },
        { where: { id: user.id } }
      ).then(() => user.reload()); // Reload the instance to get fresh data
    })
    .then(updatedUser => {
      expect(updatedUser.name).to.equal('New Name');
      done();
    })
    .catch(err => done(err));
});

Other Quick Checks

  • Test Database Isolation: Make sure you’re using a separate test database, and that you’re cleaning up data between tests (use beforeEach/afterEach to create/drop tables or truncate rows). Dirty test data can cause unexpected failures.
  • Sequelize Connection: Verify your test setup is correctly initializing Sequelize (e.g., using sync({ force: true }) in a before hook to reset tables before tests run).
  • Uncaught Promises: If you see errors about unhandled promise rejections, double-check that every promise has a .catch() (or is wrapped in try/catch for async/await).

Hopefully these fixes resolve your done() errors and get your create/update tests passing smoothly!

内容的提问来源于stack exchange,提问作者Sean Kelly

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:52:25