Mocha使用supertest,typeError:无法读取未定义的属性“ call”

时间:2018-08-05 10:02:33

标签: node.js testing mocha supertest

我正在学习对基本的Todo应用程序使用异步测试。 但是我在为我的应用程序开发测试套件时发现了一个错误,

我想使用测试套件删除待办事项。

这是我的代码:

app.delete('/todos/:id', (req,res) => {
    const id = req.params.id ;

    if(!ObjectID.isValid(id))
        return res.status(400).send();

    Todo.findByIdAndRemove(id)
    .then((todo) => {
        res.send(todo);
    }, (error) => {
        res.status(404).send();
    });        
});

这是测试套件的代码:

const todos = [{
        _id: new ObjectId(),
        text: 'first Todo'
    },
    {
        _id: new ObjectId(),
        text: 'Second Todo'
    }
];

beforeEach((done) => {
    Todo.remove({}).then(() => {
        return Todo.insertMany(todos);
        done();
    }).then(() => {
        done();
    }).catch(e => {
        console.log(e);
        done();
    });
});

describe('DELETE /todos/:id', () => {
    it('should delete a todo', (done) => {

        request(app)
            .delete(`/todos/${todos[1]._id.toHexString()}`)
            .expect(200)
            .end(done());
    });
});

我正在发现一个错误,例如:

 Uncaught TypeError: Cannot read property 'call' of undefined
      at Test.assert (node_modules/supertest/lib/test.js:181:6)
      at Server.assert (node_modules/supertest/lib/test.js:131:12)
      at emitCloseNT (net.js:1655:8)
      at _combinedTickCallback (internal/process/next_tick.js:135:11)
      at process._tickCallback (internal/process/next_tick.js:180:9)

谢谢

3 个答案:

答案 0 :(得分:1)

您要在测试用例完成之前致电done()。这似乎是问题所在。

request(app)
  .delete(`/todos/${todos[1]._id.toHexString()}`)
  .expect(200)
  .end(done); // pass the callback, not the result of executing the callback

答案 1 :(得分:0)

我想这是由于done通话不整洁所致。我的建议是避免使用done,因为mocha通过指定return来保证功能来支持保证。

我正在帮助您改进以下代码:

const todos = [{
    _id: new ObjectId(),
    text: 'first Todo'
  },
  {
    _id: new ObjectId(),
    text: 'Second Todo'
  }
];

beforeEach(() => {
  // I removed `done` and add `return` 
  return Todo.remove({})
    .then(() => {
      return Todo.insertMany(todos);
    }).catch(e => {
      console.log(e);
    });
});

describe('DELETE /todos/:id', () => {
  it('should delete a todo', () => {
    return request(app)
      .delete(`/todos/${todos[1]._id.toHexString()}`)
      .expect(200);
  });
});

比较干净,不是吗?

希望有帮助

答案 2 :(得分:0)

我有同样的问题。因为使用 .end(done()) 代替 .end(完成) 这是正确的。