Skip to content

Instantly share code, notes, and snippets.

@Ciantic
Created April 16, 2019 17:50
Show Gist options
  • Save Ciantic/be6a8b8ca27ee15e2223f642b5e01549 to your computer and use it in GitHub Desktop.
Save Ciantic/be6a8b8ca27ee15e2223f642b5e01549 to your computer and use it in GitHub Desktop.
Example of testing TypeOrm with Jest and Sqlite in-memory database
import { createConnection, getConnection, Entity, getRepository } from "typeorm";
import { PrimaryGeneratedColumn, Column } from "typeorm";
@Entity()
export class MyEntity {
@PrimaryGeneratedColumn()
id?: number;
@Column()
name?: string;
}
beforeEach(() => {
return createConnection({
type: "sqlite",
database: ":memory:",
dropSchema: true,
entities: [MyEntity],
synchronize: true,
logging: false
});
});
afterEach(() => {
let conn = getConnection();
return conn.close();
});
test("store Joe and fetch it", async () => {
await getRepository(MyEntity).insert({
name: "Joe"
});
let joe = await getRepository(MyEntity).find({
where: {
id: 1
}
});
expect(joe[0].name).toBe("Joe");
});
test("store Another and fetch it", async () => {
await getRepository(MyEntity).insert({
name: "Another"
});
let joe = await getRepository(MyEntity).find({
where: {
id: 1
}
});
expect(joe[0].name).toBe("Another");
});
@jeffreycahyono
Copy link

Wow Great! useful instead of mocking the connection

@redamsy
Copy link

redamsy commented Jan 15, 2021

when i do this it gives me empty result, even though i am running migration before each test and other services which don't have entities are working fine. this is my db.config:

import * as Knex from 'knex';
export const config: Knex.Config = {
  client: 'sqlite',
  connection: ':memory:',
  useNullAsDefault: true,
  migrations: {
    directory: 'src/db/migrations',
    tableName: 'knex_migrations',
    extension: 'ts',
  },
  seeds: {
    directory: 'src/db/test-seeds',
  },
};

let db = null;

if (process.env.NODE_ENV === 'test') {
  console.log('process.env.NODE_ENV', process.env.NODE_ENV)
  db = new (Knex as any)(config);
}

module.exports = db;

@Ciantic
Copy link
Author

Ciantic commented Jan 15, 2021

@redamsy do you have return in both beforeEach and afterEach like in mine? It needs the return statement with the connection.

@redamsy
Copy link

redamsy commented Jan 16, 2021

i wrote it like this and it worked: "file:memdb1?mode=memory&cache=shared"

@sherwinwater
Copy link

Thank you!

@dncnkrs
Copy link

dncnkrs commented Feb 3, 2021

@redamsy do you have return in both beforeEach and afterEach like in mine? It needs the return statement with the connection.

Yes. Jest needs to know when these tasks have finished, and createConnection is an async method. It's returning a promise, that resolves with the connection when it's complete.

The alternative is making the beforeEach async itself, then awaiting the createConnection call.

@hendrixroa
Copy link

Works like a charm!

@oreyne
Copy link

oreyne commented Aug 3, 2021

THANK YOU SO MUCH!

@TopherThomas
Copy link

TopherThomas commented Aug 10, 2021

Does no one else get a DriverPackageNotInstalledError: SQLite package has not been found installed. Try to install it: npm install sqlite3 --save?

edit: I started to encounter the same problem when running npm run start, when originally my app could connect to sqlite. Found out it was not just a testing problem. The fix was that I needed to delete my node_modules and build folders. Leaving this here incase it helps anyone else.

@gitDylanHub
Copy link

I am sure this works but the fundamental basis of unit testing is to have the ability to mock out external dependencies. Here, you're taking the external dependency (the database) and just redefining one for a test scenario. This fits more of an E2E model, not so much a unit testing model. Not that what kind of test is called out.

However, seems to be a common paradigm when coming to TypeORM is to generate an in-memory database for any kind of testing purposes. Goes against unit testing in my opinion. If you don't have access to the internet, how will you install the dependencies needed to test the code?

@TopherThomas
Copy link

TopherThomas commented Aug 12, 2021

I 100% agree these are not unit test. But are a form of integration test. Which was my purpose of searching out this solution, to find a way to write automated IT for my routes. To anyone wanting to write actual unit test, I mocked out TypeORM the following way.

const mockRepository = {
  findOne: jest.fn(),
  save: jest.fn(),
};

jest.mock('typeorm', () => ({
  getRepository: () => {
    return mockRepository;
  },
}));

// In Service
const myRepository = getRepository(MyObject);
await myRepository(myobject);

@vagnerwentz
Copy link

I would like to know how can I mock the generated uuid when my id property has PrimaryGeneratedColumn('uuid'). Who can help?

@andresjesse
Copy link

perfect, thanks!

@VladPetriv
Copy link

Thanks

@BenFortner
Copy link

BenFortner commented Feb 5, 2022

@vagnerwentz you can generate uuid's by importing the v4 method from uuid.


import { v4 as uuidv4} from 'uuid';

const id = uuidv4();


@ayoubjamouhi
Copy link

Thank You

@pang0103
Copy link

pang0103 commented Jul 26, 2022

Anyone ran into exception:

DataTypeNotSupportedError: Data type "timestamp" in "SomeTable.CTS" is not supported by "sqlite" database.

Seems sqlite does not support "timestamp", any alternative approach ?

https://deno.land/x/[email protected]/docs/entities.md#column-types-for-sqlite--cordova--react-native--expo

@alexdw
Copy link

alexdw commented Oct 31, 2022

@pang0103 try to use better-sqlite3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment