GET 方法在 Node.js Express 后端应用程序上失败

GET Method failing on Node.js Express backend application

我正在尝试使用 Node.js 和 Express 创建后端应用程序以从 .json 文件获取 post 和修改用户数据。这是我的 app.js 文件:

const express = require("express");
const fs = require("fs");

//setting up the express router
const app = express();

app.use(express.json());

//write the code for routes here
app.post("/add", function(req, resp){

 var jsonObject = req.body;
 var jsonFile = fs.readFileSync("get.json", "UTF8");
 var jsonArray = JSON.parse(jsonFile);
 jsonArray.push(jsonObject);

 jsonFile = JSON.stringify(jsonArray);
 resp.json(jsonFile);
 fs.writeFileSync("get.json",jsonFile,"utf-8");

});
app.get('/view/:id?', function(req, resp){
  var queryURL = url.parse(req.url, true).query;
  var jsonFile = fs.readFileSync("get.json", "UTF8");
  var data = JSON.parse(jsonFile);
  var id = req.params.id;
  // if(typeof queryURL.id === "undefined" || queryURL.id == 0){
  //   resp.json(data);
  // }else{
  //   resp.json(data[queryURL.id-1]);
  // }
  if (id >= 0) {
    data.array.every(user => {
        if (user.id === id) {  
            resp.json(user);
            return false;
        } else {
            console.log("Next")
        }
    });
  } else{
    resp.json(data);
  }

});

app.patch("/edit/:id", function(req, res){
    let userID = req.params.id;
    let userFile = fs.readFileSync("get.json", "UTF-8");
    let userArray = JSON.parse(userFile);
    
    let reqUserObject = req.body;

    let newUserArray = userArray.map(user => {
        if (user.id === userID) {
            updatedUser = {...user, ...reqUserObject};
            return updatedUser;
        } else {
            return user;
        }
    });
    
    userFileData = JSON.stringify(newUserArray);
    res.json(userFileData);
    fs.writeFileSync("get.json", userFileData, "UTF-8");
});
module.exports = app;

之外的所有方法都有效

app.get('/view/:id?', function(req, resp)

此方法有一个可选的查询参数 id,如果您传递一个 id,您将获得一个 id 等于该 id 的用户。如果你不传入 id,你会得到来自 get.json.

的所有用户

我使用的json文件(get.json)是:

[{"id":"1","name":"updated name","age":"22","gender":"Male","email":"userone@gmail.com"},{"id":"2","name":"user two","age":"24","gender":"Female","email":"usertwo@gmail.com"},{"id":"3","name":"user three","age":"23","gender":"Male","email":"userthree@gmail.com"},{"id":"4","name":"user four","age":"21","gender":"Male","email":"userfour@gmail.com"}]

我的测试文件是:

const request = require("supertest");
const app = require("../app");
const md5 = require("md5");
const fs = require("fs");

//updating a user profile
test("Updating a user", async () => {
  await request(app)
    .patch("/edit/1")
    .send({
      name: "updated name",
    })
    .expect(200);
  setTimeout(() => {
    const data = JSON.parse(fs.readFileSync("../post.json"));
    expect(data.length).toBe(5);
    expect(data[0].name).toBe("updated name");
  }, 1000);
});

// // posting a data
test("Posting a new data", async () => {
  await request(app)
    .post("/add")
    .send({
      id: "5",
      name: "user new",
      age: "36",
      gender: "Female",
      email: "usernew@gmail.com",
    })
    .expect(200);
  setTimeout(() => {
    const data = JSON.parse(fs.readFileSync("../post.json"));
    expect(data.length).toBe(5);
  }, 1000);
});

//checking the get route
test("Getting all the user data", async () => {
  const response = await request(app).get("/view").expect(200);
  expect(response.body.length).toBe(4);
  expect(md5(response.body)).toBe("f1d3ff8443297732862df21dc4e57262");
});

//getting profile of a user based on id
test("Getting a single user data", async () => {
  const response = await request(app).get("/view?id=2").expect(200);
  expect(response.body.length).toBe(1);
  expect(md5(response.body)).toBe("93b885adfe0da089cdf634904fd59f71");
});

当我 运行 我得到的测试:

rm -rf ./test-report.xml && CI=true ./node_modules/.bin/jest --testResultsProcessor ./node_modules/jest-junit-reporter --forceExit; t-reporter --forceExit;.bin/jest --testResultsProcessor ./node_modules/jest-juni FAIL test/app.test.js ✓ Updating a user (45ms) ✓ Posting a new data (17ms) ✕ Getting all the user data (10ms) ✕ Getting a single user data (4ms)

● Getting all the user data

expected 200 "OK", got 500 "Internal Server Error"

  39 | //checking the get route
  40 | test("Getting all the user data", async () => {
> 41 |   const response = await request(app).get("/view").expect(200);
     |                                                    ^
  42 |   expect(response.body.length).toBe(4);
  43 |   expect(md5(response.body)).toBe("f1d3ff8443297732862df21dc4e57262");
  44 | });

  at Object.<anonymous>.test (test/app.test.js:41:52)
  ----
  at Test._assertStatus (node_modules/supertest/lib/test.js:252:14)
  at node_modules/supertest/lib/test.js:306:17
  at Test._assertFunction (node_modules/supertest/lib/test.js:285:13)
  at Test.assert (node_modules/supertest/lib/test.js:164:23)
  at Server.localAssert (node_modules/supertest/lib/test.js:120:14)

● Getting a single user data

expected 200 "OK", got 500 "Internal Server Error"

  46 | //getting profile of a user based on id
  47 | test("Getting a single user data", async () => {
> 48 |   const response = await request(app).get("/view?id=2").expect(200);
     |                                                         ^
  49 |   expect(response.body.length).toBe(1);
  50 |   expect(md5(response.body)).toBe("93b885adfe0da089cdf634904fd59f71");
  51 | });

  at Object.<anonymous>.test (test/app.test.js:48:57)
  ----
  at Test._assertStatus (node_modules/supertest/lib/test.js:252:14)
  at node_modules/supertest/lib/test.js:306:17
  at Test._assertFunction (node_modules/supertest/lib/test.js:285:13)
  at Test.assert (node_modules/supertest/lib/test.js:164:23)
  at Server.localAssert (node_modules/supertest/lib/test.js:120:14)

Test Suites: 1 failed, 1 total Tests: 2 failed, 2 passed, 4 total Snapshots: 0 total Time: 1.612s Ran all test suites. Force exiting Jest: Have you considered using --detectOpenHandles to detect async operations that kept running after all tests finished?

我们可以看到最后两个测试(“获取所有用户数据”和“获取单个用户数据”)没有通过。这两个测试 app.get('/view/:id?', function(req, resp) 方法。

如何修复我的 app.get('/view/:id?', function(req, resp) 方法?

更新:

我按照Yago Biermann的建议修复了我的app.js,但还是无法通过最后2次测试。我修改后的app.js:

const express = require("express");
const fs = require("fs");

//setting up the express router
const app = express();

app.use(express.json());

//write the code for routes here
app.post("/add", function(req, resp){

 var jsonObject = req.body;
 var jsonFile = fs.readFileSync("get.json", "UTF8");
 var jsonArray = JSON.parse(jsonFile);
 jsonArray.push(jsonObject);

 jsonFile = JSON.stringify(jsonArray);
 resp.json(jsonFile);
 fs.writeFileSync("get.json",jsonFile,"utf-8");

});
app.get('/view', function(req, resp) {
  
  const id = req.query.id;
  var jsonFile = fs.readFileSync("get.json", "UTF8");
  var data = JSON.parse(jsonFile);
  // return the whole data if query parameter wasn't provided
  if (!id) return resp.status(200).json(data)

  // you should use find instead of every to get the user data
  const user = data.find(user => {
    if (user.id === id) {
      return user;
    };
      return null;
  });
  // return the user otherwise return a 404 response
  return user ? resp.status(200).json(user) : resp.status(404).json({message:"user not found"})
});

app.patch("/edit/:id", function(req, res){
    let userID = req.params.id;
    let userFile = fs.readFileSync("get.json", "UTF-8");
    let userArray = JSON.parse(userFile);
    
    let reqUserObject = req.body;

    let newUserArray = userArray.map(user => {
        if (user.id === userID) {
            updatedUser = {...user, ...reqUserObject};
            return updatedUser;
        } else {
            return user;
        }
    });
    
    userFileData = JSON.stringify(newUserArray);
    res.json(userFileData);
    fs.writeFileSync("get.json", userFileData, "UTF-8");
});
module.exports = app;

以及我在 运行 测试时得到的结果:

rter --forceExit;es/.bin/jest --testResultsProcessor ./node_modules/jest-junit-repo FAIL test/app.test.js ✓ Updating a user (43ms) ✓ Posting a new data (15ms) ✕ Getting all the user data (9ms) ✕ Getting a single user data (4ms)

● Getting all the user data

expect(received).toBe(expected) // Object.is equality

Expected: 4
Received: 5

  40 | test("Getting all the user data", async () => {
  41 |   const response = await request(app).get("/view").expect(200);
> 42 |   expect(response.body.length).toBe(4);
     |                                ^
  43 |   expect(md5(response.body)).toBe("f1d3ff8443297732862df21dc4e57262");
  44 | });
  45 |

  at Object.<anonymous>.test (test/app.test.js:42:32)

● Getting a single user data

expect(received).toBe(expected) // Object.is equality

Expected: 1
Received: undefined

  47 | test("Getting a single user data", async () => {
  48 |   const response = await request(app).get("/view?id=2").expect(200);
> 49 |   expect(response.body.length).toBe(1);
     |                                ^
  50 |   expect(md5(response.body)).toBe("93b885adfe0da089cdf634904fd59f71");
  51 | });
  52 |

  at Object.<anonymous>.test (test/app.test.js:49:32)

Test Suites: 1 failed, 1 total Tests: 2 failed, 2 passed, 4 total Snapshots: 0 total Time: 1.71s Ran all test suites. Force exiting Jest: Have you considered using --detectOpenHandles to detect async operations that kept running after all tests finished?

问题似乎出在你的测试中,在你的测试中"Getting all the user data"你正在向/view发出请求但你没有任何可查看的路由,至少它不在你的问题,请注意 /view/:id/view 不同。最后,在您的测试 "Getting a single user data" 中,您没有为用户提供 ID 作为 url 参数 ,而是将其作为 传递查询参数,所以尝试执行以下操作:

test("Getting a single user data", async () => {
  // pass the id as url
  const response = await request(app).get("/view/2").expect(200);
  expect(response.params.id).toBe(2);
  expect(response.body.length).toBe(1);
  expect(md5(response.body)).toBe("93b885adfe0da089cdf634904fd59f71");
});

请参阅有关 req.params 的文档。希望我有所帮助!

编辑: 正如您所说的无法更改测试文件,请在您的 view 路径中执行以下操作:

// Change to view, now the test on route /view should work
app.get('/view', function(req, resp) {
  
  const id = req.query.id;
  var jsonFile = fs.readFileSync("get.json", "UTF8");
  var data = JSON.parse(jsonFile);
  // return the whole data if query parameter wasn't provided
  if (!id) return resp.status(200).json(data)

  // you should use find instead of every to get the user data
  const user = data.find(user => {
    if (user.id === id) {
      return user;
    };
      return null;
  });
  // return the user otherwise return a 404 response
  return user ? resp.status(200).json([user]) : resp.status(404).json({message:"user not found"})
});