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"})
});
我正在尝试使用 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"})
});