generated from expressots/expressots-project-template
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add unit tests for various utility functions and application li…
…fecycle methods
- Loading branch information
1 parent
fd2551e
commit d3d91b0
Showing
24 changed files
with
1,915 additions
and
0 deletions.
There are no files selected for viewing
55 changes: 55 additions & 0 deletions
55
src/adapter-express/application-express.base.early.spec/configureServices.early.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
// Unit tests for: configureServices | ||
|
||
import { ApplicationBase } from "../application-express.base"; | ||
|
||
class ConcreteApplication extends ApplicationBase { | ||
private servicesConfigured: boolean = false; | ||
|
||
protected async globalConfiguration(): Promise<void> { | ||
} | ||
|
||
protected async configureServices(): Promise<void> { | ||
this.servicesConfigured = true; | ||
} | ||
|
||
protected async postServerInitialization(): Promise<void> { | ||
} | ||
|
||
protected async serverShutdown(): Promise<void> { | ||
} | ||
|
||
public isServicesConfigured(): boolean { | ||
return this.servicesConfigured; | ||
} | ||
} | ||
|
||
describe("ApplicationBase.configureServices() configureServices method", () => { | ||
let app: ConcreteApplication; | ||
|
||
beforeEach(() => { | ||
app = new ConcreteApplication(); | ||
}); | ||
|
||
describe("Happy Path", () => { | ||
it("should configure services successfully", async () => { | ||
await (app as any).configureServices(); | ||
expect(app.isServicesConfigured()).toBe(true); | ||
}); | ||
}); | ||
|
||
describe("Edge Cases", () => { | ||
it("should handle repeated calls to configureServices gracefully", async () => { | ||
await (app as any).configureServices(); | ||
await (app as any).configureServices(); | ||
expect(app.isServicesConfigured()).toBe(true); | ||
}); | ||
|
||
it("should handle asynchronous operations correctly", async () => { | ||
const configureServicesSpy = jest.spyOn(app as any, "configureServices"); | ||
await (app as any).configureServices(); | ||
expect(configureServicesSpy).toHaveBeenCalled(); | ||
}); | ||
}); | ||
}); | ||
|
||
// End of unit tests for: configureServices |
75 changes: 75 additions & 0 deletions
75
src/adapter-express/application-express.base.early.spec/globalConfiguration.early.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
// Unit tests for: globalConfiguration | ||
|
||
import { ApplicationBase } from "../application-express.base"; | ||
|
||
class ConcreteApplication extends ApplicationBase { | ||
private config: any; | ||
|
||
constructor() { | ||
super(); | ||
this.config = {}; | ||
} | ||
|
||
protected async globalConfiguration(): Promise<void> { | ||
this.config = { setting: "value" }; | ||
} | ||
|
||
protected async configureServices(): Promise<void> {} | ||
protected async postServerInitialization(): Promise<void> {} | ||
protected async serverShutdown(): Promise<void> {} | ||
|
||
public async callGlobalConfiguration(): Promise<void> { | ||
await this.globalConfiguration(); | ||
} | ||
|
||
public getConfig(): any { | ||
return this.config; | ||
} | ||
} | ||
|
||
describe("ApplicationBase.globalConfiguration() globalConfiguration method", () => { | ||
let app: ConcreteApplication; | ||
|
||
beforeEach(() => { | ||
app = new ConcreteApplication(); | ||
}); | ||
|
||
describe("Happy Path", () => { | ||
it("should set the global configuration correctly", async () => { | ||
// Access indirectly via public method | ||
await app.callGlobalConfiguration(); | ||
expect(app.getConfig()).toEqual({ setting: "value" }); | ||
}); | ||
}); | ||
|
||
describe("Edge Cases", () => { | ||
it("should handle asynchronous operations correctly", async () => { | ||
const asyncConfigApp = new (class extends ConcreteApplication { | ||
protected async globalConfiguration(): Promise<void> { | ||
return new Promise((resolve) => { | ||
setTimeout(() => { | ||
this["config"] = { asyncSetting: "asyncValue" }; // Access private attribute indirectly | ||
resolve(); | ||
}, 100); | ||
}); | ||
} | ||
})(); | ||
|
||
await asyncConfigApp.callGlobalConfiguration(); | ||
expect(asyncConfigApp.getConfig()).toEqual({ asyncSetting: "asyncValue" }); | ||
}); | ||
|
||
it("should handle empty configuration gracefully", async () => { | ||
const emptyConfigApp = new (class extends ConcreteApplication { | ||
protected async globalConfiguration(): Promise<void> { | ||
this["config"] = {}; // Access private attribute indirectly | ||
} | ||
})(); | ||
|
||
await emptyConfigApp.callGlobalConfiguration(); | ||
expect(emptyConfigApp.getConfig()).toEqual({}); | ||
}); | ||
}); | ||
}); | ||
|
||
// End of unit tests for: globalConfiguration |
47 changes: 47 additions & 0 deletions
47
...dapter-express/application-express.base.early.spec/postServerInitialization.early.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// Unit tests for: postServerInitialization | ||
|
||
import { ApplicationBase } from "../application-express.base"; | ||
|
||
class ConcreteApplication extends ApplicationBase { | ||
protected globalConfiguration(): void | Promise<void> {} | ||
protected configureServices(): void | Promise<void> {} | ||
|
||
protected async postServerInitialization(): Promise<void> { | ||
console.log("Server initialized"); | ||
} | ||
|
||
protected serverShutdown(): void | Promise<void> {} | ||
|
||
public async callPostServerInitialization(): Promise<void> { | ||
await this.postServerInitialization(); | ||
} | ||
} | ||
|
||
describe("ApplicationBase.postServerInitialization() postServerInitialization method", () => { | ||
let app: ConcreteApplication; | ||
|
||
beforeEach(() => { | ||
app = new ConcreteApplication(); | ||
}); | ||
|
||
describe("Happy Path", () => { | ||
it("should execute postServerInitialization without errors", async () => { | ||
await expect(app.callPostServerInitialization()).resolves.toBeUndefined(); | ||
}); | ||
}); | ||
|
||
describe("Edge Cases", () => { | ||
it("should handle asynchronous operations correctly", async () => { | ||
jest.spyOn(app as any, "postServerInitialization").mockResolvedValueOnce(undefined); | ||
await expect(app.callPostServerInitialization()).resolves.toBeUndefined(); | ||
}); | ||
|
||
it("should handle errors thrown within the method", async () => { | ||
const error = new Error("Initialization error"); | ||
jest.spyOn(app as any, "postServerInitialization").mockRejectedValueOnce(error); | ||
await expect(app.callPostServerInitialization()).rejects.toThrow("Initialization error"); | ||
}); | ||
}); | ||
}); | ||
|
||
// End of unit tests for: postServerInitialization |
49 changes: 49 additions & 0 deletions
49
src/adapter-express/application-express.base.early.spec/serverShutdown.early.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
// Unit tests for: serverShutdown | ||
|
||
import { ApplicationBase } from "../application-express.base"; | ||
|
||
export class ConcreteApplication extends ApplicationBase { | ||
protected globalConfiguration(): void | Promise<void> {} | ||
protected configureServices(): void | Promise<void> {} | ||
protected postServerInitialization(): void | Promise<void> {} | ||
|
||
protected async serverShutdown(): Promise<void> { | ||
return new Promise((resolve) => { | ||
setTimeout(() => { | ||
resolve(); | ||
}, 100); | ||
}); | ||
} | ||
|
||
public async callServerShutdown(): Promise<void> { | ||
return this.serverShutdown(); | ||
} | ||
} | ||
|
||
describe("ApplicationBase.serverShutdown() serverShutdown method", () => { | ||
let app: ConcreteApplication; | ||
|
||
beforeEach(() => { | ||
app = new ConcreteApplication(); | ||
}); | ||
|
||
describe("Happy Path", () => { | ||
it("should resolve the promise indicating successful shutdown", async () => { | ||
await expect(app.callServerShutdown()).resolves.toBeUndefined(); | ||
}); | ||
}); | ||
|
||
describe("Edge Cases", () => { | ||
it("should handle immediate resolution without delay", async () => { | ||
jest.spyOn(app as any, "serverShutdown").mockResolvedValueOnce(undefined); | ||
await expect(app.callServerShutdown()).resolves.toBeUndefined(); | ||
}); | ||
|
||
it("should handle rejection gracefully", async () => { | ||
jest.spyOn(app as any, "serverShutdown").mockRejectedValueOnce(new Error("Shutdown failed")); | ||
await expect(app.callServerShutdown()).rejects.toThrow("Shutdown failed"); | ||
}); | ||
}); | ||
}); | ||
|
||
// End of unit tests for: serverShutdown |
82 changes: 82 additions & 0 deletions
82
src/adapter-express/application-express.early.spec/configContainer.early.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
// Unit tests for: configContainer | ||
|
||
import { interfaces } from "../../di/di.interfaces"; | ||
import { AppExpress } from "../application-express"; | ||
|
||
jest.mock("@expressots/core", () => ({ | ||
ExpressoMiddleware: class {}, | ||
AppContainer: jest.fn().mockImplementation(() => new MockAppContainer() as any), | ||
Logger: jest.fn().mockImplementation(() => new MockLogger() as any), | ||
ProviderManager: jest.fn().mockImplementation(() => new MockProviderManager() as any), | ||
Middleware: jest.fn().mockImplementation(() => new MockMiddleware() as any), | ||
Console: jest.fn().mockImplementation(() => new MockConsole() as any), | ||
injectable: () => (target: any) => target, | ||
inject: jest.fn(() => jest.fn()), | ||
})); | ||
|
||
class MockLogger { | ||
error = jest.fn(); | ||
} | ||
|
||
class MockProviderManager { | ||
constructor() {} | ||
} | ||
|
||
class MockMiddleware { | ||
getMiddlewarePipeline = jest.fn().mockReturnValue([]); | ||
} | ||
|
||
class MockAppContainer { | ||
Container = {}; | ||
create = jest.fn(); | ||
} | ||
|
||
class MockConsole { | ||
messageServer = jest.fn(); | ||
} | ||
|
||
describe("AppExpress.configContainer() configContainer method", () => { | ||
let appExpress: AppExpress; | ||
|
||
beforeEach(() => { | ||
appExpress = new AppExpress(); | ||
}); | ||
|
||
describe("Happy Path", () => { | ||
it("should configure the container with provided modules", () => { | ||
const mockModules: Array<interfaces.ContainerModule> = [{} as any]; | ||
const mockOptions: interfaces.ContainerOptions = {} as any; | ||
|
||
const result = appExpress.configContainer(mockModules, mockOptions); | ||
|
||
expect(result).toBeInstanceOf(MockAppContainer); | ||
expect(result.create).toHaveBeenCalledWith(mockModules); | ||
}); | ||
|
||
it("should configure the container with default options if none are provided", () => { | ||
const mockModules: Array<interfaces.ContainerModule> = [{} as any]; | ||
|
||
const result = appExpress.configContainer(mockModules); | ||
|
||
expect(result).toBeInstanceOf(MockAppContainer); | ||
expect(result.create).toHaveBeenCalledWith(mockModules); | ||
}); | ||
}); | ||
|
||
describe("Edge Cases", () => { | ||
it("should log an error if no modules are provided", () => { | ||
const mockLogger = new MockLogger(); | ||
appExpress["logger"] = mockLogger as any; | ||
|
||
const result = appExpress.configContainer(undefined as any); | ||
|
||
expect(result).toBeUndefined(); | ||
expect(mockLogger.error).toHaveBeenCalledWith( | ||
"No modules provided for container configuration", | ||
"adapter-express", | ||
); | ||
}); | ||
}); | ||
}); | ||
|
||
// End of unit tests for: configContainer |
Oops, something went wrong.