Express POST API 路由未收到超测请求

Express POST API Route not receiving a Supertest request

我正在尝试测试 Express API POST 使用 Express Validator 的路由 check:

usersRouter.post(
  '/',
  [
    check('name', 'Please enter a name.').not().isEmpty(),
    check('email', 'Please enter a valid email.').isEmail(),
    check(
      'password',
      'Please enter a password of 6 characters or more.'
    ).isLength({ min: 6 }),
  ],
  async (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      console.log('errors: ', errors);
      return res.status(400).json({ errors: errors.array() });
    }

    const { name, email, password } = req.body;
    
    try {
        //...
    }
    catch {
        //...
    }
  }
);

此 API 路由希望收到一个请求,该请求由包含字段 nameemailpassword:

的正文组成
const { name, email, password } = req.body

为了测试这条路线,我有一个使用 supertestjest:

的测试文件
const mongoose = require('mongoose');
const supertest = require('supertest');
const app = require('../app');
const testApi = supertest(app);
const User = require('../models/User');

test('a token is returned', async () => {
  // Create a new test user for the HTTP request.
  const newTestUser = {
    name: 'bob',
    email: 'test@test.com',
    password: 'newtestpw',
  };
  const { name, email, password } = newTestUser;
  const body = await JSON.stringify({ name, email, password });

  // Execute the test.
  const config = {
    headers: {
      'Content-Type': 'application/json',
    },
  };
  let result = await testApi.post('/api/users', body, config);

  expect(result.status).toBe(200);
  expect(result.headers).toHaveProperty('token');
});

afterAll(async () => {
  await mongoose.connection.close();
});

当我执行此测试时,POST API 路由中的每个 check 都失败了。返回以下 errors

    errors:  Result {
      formatter: [Function: formatter],
      errors:
       [ { value: undefined,
           msg: 'Please enter a name.',
           param: 'name',
           location: 'body' },
         { value: undefined,
           msg: 'Please enter a valid email.',
           param: 'email',
           location: 'body' },
         { value: undefined,
           msg: 'Please enter a password of 6 characters or more.',
           param: 'password',
           location: 'body' } ] }

为什么 API 路由没有收到我使用 Supertest 发送的请求?

嗯,看来您没有正确发送您的值。 仔细查看您发送姓名、电子邮件和密码的位置以及发送方式。您可以尝试转到您的路线并 console.log 它获得的值。 并查看 api.post 函数的实际工作原理。我建议查看 Supertest github page and Superagent docs

以防万一您想尝试自己解决问题,我在剧透中隐藏了解决方案。但总而言之,首先:

您不需要将 body 字符串化。您应该照常发送 JavaScript object。此外,您不需要等待 JSON.stringify,因为它不是 return 承诺,它是同步的

第二个:

api.post 函数仅将 URL 作为参数。要发送您想要的任何数据以及您需要在 .post

之后链接 .send(data) 的请求

第三名:

headers 也可以通过在 .send

之前或之后链接 .set('Header', 'value') 方法来设置

所以最后,您的请求应该是这样的。

testApi
  .post(url)
  .set('Content-Type', 'application/json')
  .send(newTestUser)