Skip to content

Commit

Permalink
Merge pull request #8 from Wathmiv/testing
Browse files Browse the repository at this point in the history
unit testing of backend
  • Loading branch information
Wathmiv authored Jan 31, 2024
2 parents 36fdb9f + a353a67 commit 6554405
Show file tree
Hide file tree
Showing 13 changed files with 5,249 additions and 1,630 deletions.
1 change: 0 additions & 1 deletion backend/.prettierrc.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
{
"singleQuote": false,
"semi": false,
"tabWidth": 2,
"printWidth": 80
}
5 changes: 5 additions & 0 deletions backend/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: "ts-jest",
testEnvironment: "node",
};
6,451 changes: 4,921 additions & 1,530 deletions backend/package-lock.json

Large diffs are not rendered by default.

7 changes: 6 additions & 1 deletion backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"scripts": {
"start": "ts-node src/index.ts",
"build": "tsc",
"test": "echo \"Error: no test specified\" && exit 1",
"test": "jest",
"lint": "eslint src/**/*.ts",
"lint:fix": "eslint --fix .",
"format": "eslint src/**/*.ts --fix"
Expand All @@ -27,13 +27,18 @@
},
"devDependencies": {
"@types/express": "^4.17.21",
"@types/jest": "^29.5.11",
"@types/node": "^20.11.5",
"@types/supertest": "^6.0.2",
"@typescript-eslint/eslint-plugin": "^6.19.0",
"@typescript-eslint/parser": "^6.19.0",
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.1.3",
"jest": "^29.7.0",
"prettier": "^3.2.4",
"supertest": "^6.3.4",
"ts-jest": "^29.1.2",
"ts-node": "^10.9.2",
"typescript": "^5.3.3"
}
Expand Down
158 changes: 158 additions & 0 deletions backend/src/__tests__/studentController.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
import { Server } from "socket.io";
import { StudentController } from "../controllers/student";
import { StudentService } from "../services/student";
import { Request, Response } from "express";

// Mock StudentService
jest.mock("../services/student", () => ({
StudentService: {
create: jest.fn(),
findAll: jest.fn(),
edit: jest.fn(),
delete: jest.fn(),
},
}));

describe("StudentController", () => {
let io: Server;
let studentController: StudentController;
let req: Partial<Request>;
let res: Partial<Response>;

beforeEach(() => {
io = new Server();
studentController = new StudentController(io);
res = {
status: jest.fn().mockReturnThis(),
json: jest.fn(),
};
});

it("should create a new student", async () => {
const mockStudent = {
id: 1,
name: "Test student",
gender: "Male",
address: "123 Test St",
mobile: "1234567890",
dob: new Date("2000-01-01"),
age: 21,
};
req = { body: { name: "Test student" } };

(jest.spyOn(StudentService, "create") as jest.Mock).mockResolvedValue(
mockStudent,
);
await studentController.create(req as Request, res as Response);
expect(res.status).toHaveBeenCalledWith(201);
expect(res.json).toHaveBeenCalledWith(mockStudent);
});

it("should return 500 if creating a student fails", async () => {
req = { body: { name: "John Doe" } };

(jest.spyOn(StudentService, "create") as jest.Mock).mockRejectedValue(
new Error(),
);

await studentController.create(req as Request, res as Response);

expect(res.status).toHaveBeenCalledWith(500);
expect(res.json).toHaveBeenCalledWith({
message: "An error occurred while creating the student.",
});
});

it("should fetch all students", async () => {
const mockStudents = [
{ id: 1, name: "Test student 1" },
{ id: 2, name: "Test student 2" },
];

req = {};

(jest.spyOn(StudentService, "findAll") as jest.Mock).mockResolvedValue(
mockStudents,
);

await studentController.findAll(req as Request, res as Response);

expect(res.status).toHaveBeenCalledWith(200);
expect(res.json).toHaveBeenCalledWith(mockStudents);
});

it("should return 500 if fetching students fails", async () => {
req = {};

(jest.spyOn(StudentService, "findAll") as jest.Mock).mockRejectedValue(
new Error(),
);

await studentController.findAll(req as Request, res as Response);

expect(res.status).toHaveBeenCalledWith(500);
expect(res.json).toHaveBeenCalledWith({
message: "An error occurred while fetching the students.",
});
});

it("should edit a student", async () => {
const mockStudent = { id: 1, name: "John Doe" };

req = {
params: { id: "1" },
body: { name: "John Doe" },
};

(jest.spyOn(StudentService, "edit") as jest.Mock).mockResolvedValue(
mockStudent,
);

await studentController.edit(req as Request, res as Response);
expect(res.status).toHaveBeenCalledWith(200);
expect(res.json).toHaveBeenCalledWith(mockStudent);
});

it("should return 500 if editing a student fails", async () => {
req = {
params: { id: "1" },
body: { name: "John Doe" },
};

(jest.spyOn(StudentService, "edit") as jest.Mock).mockRejectedValue(
new Error(),
);

await studentController.edit(req as Request, res as Response);

expect(res.status).toHaveBeenCalledWith(500);
expect(res.json).toHaveBeenCalledWith({
message: "An error occurred while editing the student.",
});
});

it("should delete a student", async () => {
req = { params: { id: "1" } };

(jest.spyOn(StudentService, "delete") as jest.Mock).mockResolvedValue(true);

await studentController.delete(req as Request, res as Response);

expect(res.status).toHaveBeenCalledWith(204);
});

it("should return 500 if deleting a student fails", async () => {
req = { params: { id: "1" } };

(jest.spyOn(StudentService, "delete") as jest.Mock).mockRejectedValue(
new Error(),
);

await studentController.delete(req as Request, res as Response);

expect(res.status).toHaveBeenCalledWith(500);
expect(res.json).toHaveBeenCalledWith({
message: "An error occurred while deleting the student.",
});
});
});
68 changes: 48 additions & 20 deletions backend/src/controllers/student.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,66 @@
import { Request, Response } from "express"
import { StudentService } from "../services/student"
import { Server } from "socket.io"
import { Request, Response } from "express";
import { StudentService } from "../services/student";
import { Server } from "socket.io";

export class StudentController {
private studentService = new StudentService()
private io: Server
// private studentService = new StudentService()
private io: Server;

constructor(io: Server) {
this.io = io
this.io = io;
}

async create(req: Request, res: Response) {
const student = await this.studentService.create(req.body)
this.io.emit("add-student", student)
res.json(student)
try {
const student = await StudentService.create(req.body);
this.io.emit("add-student", student);
res.status(201).json(student); // 201 status code for created
} catch (error) {
console.error(error);
res
.status(500)
.json({ message: "An error occurred while creating the student." });
}
}

async findAll(req: Request, res: Response) {
const students = await this.studentService.findAll()
res.json(students)
try {
const students = await StudentService.findAll();
res.status(200).json(students);
} catch (error) {
console.error(error);
res
.status(500)
.json({ message: "An error occurred while fetching the students." });
}
}

async edit(req: Request, res: Response) {
const student = await this.studentService.edit(
Number(req.params.id),
req.body,
)
this.io.emit("edit-student", student)
res.json(student)
try {
const student = await StudentService.edit(
Number(req.params.id),
req.body,
);
this.io.emit("edit-student", student);
res.status(200).json(student);
} catch (error) {
console.error(error);
res
.status(500)
.json({ message: "An error occurred while editing the student." });
}
}

async delete(req: Request, res: Response) {
await this.studentService.delete(Number(req.params.id))
this.io.emit("delete-student")
res.status(204).send()
try {
await StudentService.delete(Number(req.params.id));
this.io.emit("delete-student");
res.status(204).send();
} catch (error) {
console.error(error);
res
.status(500)
.json({ message: "An error occurred while deleting the student." });
}
}
}
76 changes: 37 additions & 39 deletions backend/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,36 @@
import express, { Express, Request, Response } from "express"
import dotenv from "dotenv"
import { DataSource } from "typeorm"
import { studentRoutes } from "./routes/studentRoute"
import cors from "cors"
import { createServer } from "node:http"
import { Server } from "socket.io"

dotenv.config()

const app: Express = express()
app.use(express.json())
const server = createServer(app)
import express, { Express } from "express";
import dotenv from "dotenv";
import { DataSource } from "typeorm";
import { studentRoutes } from "./routes/studentRoute";
import cors from "cors";
import { createServer } from "node:http";
import { Server } from "socket.io";

dotenv.config();

const app: Express = express();
app.use(express.json());
export const server = createServer(app);
const io = new Server(server, {
cors: {
origin: "http://localhost:3000",
},
})
});

io.on("connection", (socket) => {
console.log("a user connected")
console.log("a user connected");
socket.on("disconnect", () => {
console.log("user disconnected")
})
})
console.log("user disconnected");
});
});

const port = process.env.PORT || 5000
const port = process.env.PORT || 5000;

app.use(
cors({
origin: "http://localhost:3000",
}),
)
);

export const AppDataSource = new DataSource({
type: "postgres",
Expand All @@ -42,22 +42,20 @@ export const AppDataSource = new DataSource({
entities: ["src/models/**/*.ts"],
synchronize: true,
logging: true,
})

AppDataSource.initialize()
.then(() => {
console.log("Data Source has been initialized!")
})
.catch((err) => {
console.error("Error during Data Source initialization", err)
})

studentRoutes(app, io)

app.get("/", (req: Request, res: Response) => {
res.send("Express + TypeScript Server")
})

server.listen(port, () => {
console.log(`[server]: Server is running at http://localhost:${port}`)
})
});
const startServer = async () => {
try {
await AppDataSource.initialize();
console.log("Data Source has been initialized!");

studentRoutes(app, io);

server.listen(port, () => {
console.log(`[server]: Server is running at http://localhost:${port}`);
});
} catch (err) {
console.error("Error during Data Source initialization", err);
}
};

startServer();
Loading

0 comments on commit 6554405

Please sign in to comment.