Skip to content

Instantly share code, notes, and snippets.

@dfee
Last active August 8, 2020 08:07
Show Gist options
  • Save dfee/297b14ee9ed4621447205ea82c5a12cd to your computer and use it in GitHub Desktop.
Save dfee/297b14ee9ed4621447205ea82c5a12cd to your computer and use it in GitHub Desktop.
Example of auto-rollback transactions with Mikro-Orm for testing
import {
Connection,
EntityManager,
IDatabaseDriver,
MikroORM,
} from "@mikro-orm/core";
import { PostgreSqlDriver } from "@mikro-orm/postgresql";
import { getConfig } from "../config";
import { UserEntity } from "../entities";
type TxOptions<T extends IDatabaseDriver<Connection>> = {
em: EntityManager<T>;
inner: (em: EntityManager<T>) => Promise<void>;
outer: (em: EntityManager<T>) => Promise<void>;
};
const tx = async <T extends IDatabaseDriver<Connection>>({
em,
inner: cbInner,
outer: cbOuter = () => Promise.resolve(),
}: TxOptions<T>) => {
const rollback = Symbol("rollback");
try {
await em.transactional(async (emOuter) => {
await emOuter.transactional(async (emInner) => {
await cbInner(emInner as EntityManager<T>);
});
await cbOuter(emOuter as EntityManager<T>);
throw rollback;
});
} catch (e) {
if (e !== rollback) {
throw e;
}
}
};
describe("create user in inner transaction, find it in outer transaction, and rollback to an empty db", () => {
const config = getConfig();
let orm: MikroORM<PostgreSqlDriver>;
beforeAll(async () => {
orm = await MikroORM.init(config);
});
afterAll(async () => {
await orm.close();
});
it("should create a user", async () => {
const user = new UserEntity({
emailAddress: "foo@bar.com",
});
await tx({
em: orm.em,
inner: async (em) => {
const userRepository = em.getRepository(UserEntity);
userRepository.persist(user);
},
outer: async (em) => {
const retrieved = await em
.getRepository(UserEntity)
.findOneOrFail(user.id);
expect(retrieved).toEqual(user);
},
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment