首页 文章

未处理的Promise拒绝警告:TypeError:第一个参数必须是字符串或缓冲区

提问于
浏览
3

问题似乎是重复的,但我一直在努力解决这个问题 . 基本上我正在使用 supertestmocha 来测试我的API . 我无法理解哪个承诺没有得到解决 .

app.post('/todos', (req, res) => {
 var todo = new Todo({
 text : req.body.text
});
 todo.save().then( (doc) => {
  res.status(200).send(doc)
  }, (e) => {
  res.status(400).end(e);
 });
});

以下是我写的测试:

const expect = require('expect');
const request = require('supertest');

var {app} = require('./../server');
var {Todo} = require('./../models/todo');

// Setup database 
beforeEach((done) => {
  Todo.remove({})
 .then(() => done())
 .catch((e)=> done(e));
}); 

describe('Post /todos', () => {
it('should create a new todo', (done) => {

var text = 'Testing text';

// supertest to get, post
request(app)
  .post('/todos')
  .send({text}) // Automatic conversion to json - ES6
  .expect(200) // assertions
  .expect((res) => { // custom parsing
    expect(res.body.text).toBe(text);
  })
  .end((err, res) => {  // done directly accepted, but rather let's be more precise now - check mongodb
    if (err) {
      return done(err);
    }
    Todo.find()
      .then((todos) => {
        expect(todos.length).toBe(1);
        expect(todos[0].text).toBe(text);
        done();
      })
      .catch((e) => done(e));
  });
 });
});

请帮忙解决这个问题 . 这是整个错误消息:

mocha server / ** / * .test.js侦听端口:3000 Post / todos(node:1882)UnhandledPromiseRejectionWarning:未处理的promise拒绝(拒绝id:1):TypeError:第一个参数必须是字符串或Buffer(节点: 1882)[DEP0018]弃用警告:弃用未处理的承诺拒绝 . 将来,未处理的承诺拒绝将使用非零退出代码终止Node.js进程 . 1)应该创建一个新的todo 0传递(2s)1失败1)Post / todos应该创建一个新的todo:错误:超过2000ms的超时 . 对于异步测试和挂钩,确保调用“done()”;如果返回Promise,请确保它已解决 .

1 回答

  • 0

    express中的 end 函数只接受字符串或缓冲区,而不是对象(请参阅https://expressjs.com/en/api.html#res.endhttps://nodejs.org/api/http.html#http_response_end_data_encoding_callback) .

    但是,它看起来像 todo.save() 用对象调用 reject ,这意味着 e 会导致 TypeError . 因为这是捕获承诺拒绝的错误,所以错误包含在 Unhandled Promise Rejection 警告中 .

    假设 e{ message: "First argument must be a string or Buffer" } ,新代码可能是:

    todo.save().then( (doc) => {
      res.status(200).send(doc)
      }, (e) => {
      res.status(400).end(e.message);
     });
    

    todo.save() 承诺被拒绝的原因可能是因为todo中的 text 似乎未定义 . 这是分配给 req 的JSON:

    {
      text: 'Testing text'
    }
    

    但是,它应该是这样的:

    {
      body: {
        text: 'Testing text'
      }
    }
    

    如果您将发送更改为此,则应修复测试:

    .send({ body: { text }) // Automatic conversion to json - ES6
    

相关问题