-
-
Save Ciantic/be6a8b8ca27ee15e2223f642b5e01549 to your computer and use it in GitHub Desktop.
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"); | |
}); |
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;
@redamsy do you have return
in both beforeEach
and afterEach
like in mine? It needs the return statement with the connection.
i wrote it like this and it worked: "file:memdb1?mode=memory&cache=shared"
Thank you!
@redamsy do you have
return
in bothbeforeEach
andafterEach
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.
Works like a charm!
THANK YOU SO MUCH!
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.
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?
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);
I would like to know how can I mock the generated uuid when my id property has PrimaryGeneratedColumn('uuid')
. Who can help?
perfect, thanks!
Thanks
@vagnerwentz you can generate uuid's by importing the v4 method from uuid.
import { v4 as uuidv4} from 'uuid';
const id = uuidv4();
Thank You
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 ?
@pang0103 try to use better-sqlite3
Wow Great! useful instead of mocking the connection