Express. js почему размещение app.use () влияет на результаты теста? - PullRequest
0 голосов
/ 16 февраля 2020

Я практикую свои знания в Express. js.

У меня есть один маршрутизатор рецептов с кодом ниже:

const express = require("express");
const router = express.Router();

const Recipe = require("../models/recipe.model");

const createRecipeItem = async recipeData => {
  await Recipe.init();
  const doc = Recipe(recipeData);
  await doc.save();
};

router.post("/", async (req, res, next) => {
  try {
    await createRecipeItem(req.body);
  } catch (err) {
    next(err);
  }
  res.status(201).send(req.body);
});

module.exports = router;

У меня есть другой маршрутизатор питания, код ниже:

const express = require("express");
const router = express.Router();

const Supply = require("../models/supply.model");

const createSupplyItem = async supplyData => {
  await Supply.init();
  const doc = Supply(supplyData);
  await doc.save();
};

const updateItem = async (name, itemData) => {
  const result = await Supply.findOneAndUpdate({ name }, itemData, {
    new: true
  });
  return result;
};

router.post("/", async (req, res, next) => {
  try {
    await createSupplyItem(req.body);
  } catch (err) {
    next(err);
  }
  const respObj = {};
  respObj.name = req.body.name;
  respObj.qty = req.body.qty;
  res.status(201).send(respObj);
});

router.patch("/:name", async (req, res, next) => {
  const updatedItem = await updateItem(req.params.name, req.body);
  const response = {};
  response.name = updatedItem.name;
  response.qty = updatedItem.qty;
  res.status(200).send(response);
});

module.exports = router;

Я написал тесты для два маршрутизатора, использующие supertest

Внутри моего приложения. js мой код написан так:

const supplyRouter = require("./routes/supply.route");
const recipeRouter = require("./routes/recipe.route");

app.use("/recipes", recipeRouter);
app.use("/supplies", supplyRouter);

когда код написан так:

app.use("/recipes", recipeRouter);
app.use("/supplies", supplyRouter);

Все мои испытания пройдены. Однако при изменении порядка вызова app.use() тест не пройден.

app.use("/supplies", supplyRouter);
app.use("/recipes", recipeRouter);

Тест не пройден с ошибкой Cannot set headers after they are sent to the client для метода POST /supplies. У меня нет четкого понимания, почему это происходит. Ценю любое понимание. Спасибо!

1 Ответ

0 голосов
/ 17 февраля 2020

Я не могу пройти мой тест правильно, потому что у меня не было правильного понимания потока кода.

router.post("/", async (req, res, next) => {
  try {
    await createSupplyItem(req.body);
  } catch (err) {
    next(err);
  }
  const respObj = {};
  respObj.name = req.body.name;
  respObj.qty = req.body.qty;
  res.status(201).send(respObj);
});

Для приведенного выше кода при возникновении ошибки express будет запускать два пути кода, а именно путь внутри блока catch и последнюю строку кода res.status(201).send(respObj);

Поскольку он пытается запустить два пути, я получил ошибку Cannot set headers after they are sent to the client.

Правильный код написан ниже.

router.post("/", async (req, res, next) => {
  try {
    await createSupplyItem(req.body);
    const respObj = {};
    respObj.name = req.body.name;
    respObj.qty = req.body.qty;
    res.status(201).send(respObj);
  } catch (err) {
    if (err.name === "ValidationError") {
      err.statusCode = 400;
    } else if (err.name === "MongoError") {
      err.statusCode = 400;
    }
    next(err);
  }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...