Im new to using typeorm and Jest for that matter. I have a function that is creating and returning a DataSource here:
app/lib/connections/createDBConnection.ts
const createDBConnection = async () => {
const dbUrl = Environment.get('DATABASE_URL')
const db = new DataSource({
type: 'postgres',
url: dbUrl,
synchronize: false,
entities: [],
connectTimeoutMS: 10000,
})
await db.initialize()
return db
}
export default createDBConnection
Here is the get function if it helps:
export class Environment {
public static get(key: string): string {
const result = process.env[key]
if (result === undefined) {
throw new Error(`Failed to find key ${key} in environment`)
}
return result
}
Here is my test file:
const FakeDB = new DataSource({
type: 'postgres',
url: 'fakeURL',
synchronize: false,
entities: [],
connectTimeoutMS: 10000,
})
jest.mock('app/lib/connections/createDBConnection', () => {
return jest.fn().mockImplementation(() => Promise.resolve(FakeDB))
}
)
afterEach(() => {
jest.clearAllMocks()
})
test('creates a fake connection', async () => {
const DbConnection = await createDBConnection()
expect(DbConnection).toBeTruthy()
expect(DbConnection).toBeInstanceOf(DataSource)
expect(DbConnection).toEqual(FakeDB)
// Im trying to make something like these pass
expect(FakeDB.initialize).toHaveBeenCalled
expect(FakeDB.isInitialized).toBe(true)
})
Im not sure how to mock out the initialize function correctly. I want to verify its called in my function somehow. The first three assertions seem to pass, but im not sure if its actually correct, since those bottom 2 both fail. Any help or advice will be appreciated.
Ive tried mocking the initialize a couple of ways like:
jest.mock('typeorm'), () => {
return jest.fn().mockImplementation(() => {
return {
initialize: () => {true}
}
})
}
Seems that you are mocking TypeORM which you shouldn't. You should trust the API and that TypeORM will return an instance of DataSource
and that it sets isInitialized=true
.
What you might do is to mock createDBConnection
in the components that are consuming it, or maybe design your code with dependency injection (DI) so you can inject your DataSource
instance in your application, or its double when testing.
And, if you still want to test that your createDBConnection
is working as expected, you may assert that Environment.get
is called with DATABASE_URL
and that db.initialize()
is called:
const mockDS = {
initialize: jest.fn(),
};
jest.mock("typeorm", () => {
return {
DataSource: jest.fn().mockImplementation(() => mockDS),
};
});
// Env
const mockEnv = {
get: jest.fn(),
};
jest.mock("src/path/to/environment/file", () => {
return {
Environment: mockEnv,
};
});
import createDBConnection from "src/app/lib/connections/createDBConnection.ts";
afterEach(() => {
jest.clearAllMocks();
});
test("calls .initialize() and env.get", async () => {
await createDBConnection();
expect(mockEnv.get).toHaveBeenCalledWith("DATABASE_URL");
expect(mockDS.initialize).toHaveBeenCalled();
});