【问题标题】:Mocha Using supertest , typeError: cannot read property 'call' of undefinedMocha 使用 supertest , typeError: cannot read property 'call' of undefined
【发布时间】:2019-01-12 13:39:15
【问题描述】:

我正在学习对我的基本 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)

谢谢

【问题讨论】:

  • 当你运行这个时,你的节点服务器在运行吗?此外,由于您的 api 已被承诺,因此您无需致电 done()。您可以改为返回完整的提交承诺对象。

标签: node.js testing mocha.js supertest


【解决方案1】:

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

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

【讨论】:

  • 如果你对 async/await 感兴趣,那么你会做await request(app).delete... expect(200)。是的,没有done
【解决方案2】:

我遇到了同样的问题。因为使用 .end(完成()) 代替 .end(完成) 哪个是正确的。

【讨论】:

    【解决方案3】:

    我猜是done调用不整齐造成的。我的建议是避免使用done,因为mocha 通过将return 指定为promise 函数来支持promise。

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

    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);
      });
    });
    

    它更干净,不是吗?

    希望对你有帮助

    【讨论】:

    • 你能解释一下为什么我们不使用 done 吗?
    • @abhigyannayak 我们仍然可以使用done,但它更适合回调函数。现在大多数异步方法都没有使用回调函数,而是通过指定 return mochajs.org/#working-with-promises 转向 Promise 和 Mocha 支持 Promise。如果我们比较代码并根据我的经验,使用return 会更容易阅读。
    • @abhigyannayak 和当前的测试趋势是使用async await mochajs.org/#using-async--await。它甚至比使用 Promise 更容易编写代码。
    猜你喜欢
    • 2013-01-15
    • 1970-01-01
    • 2021-06-25
    • 2017-04-24
    • 2023-03-15
    • 2021-09-18
    • 2021-09-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多