-
Hi, As many tests hit the same database, I chose to wrap each test in a transaction to effectively isolate each test against the changes performed by all other tests. So I have code like this: // setUpAll to create an in-memory database
// tearDownAll to db.close()
test('something', () async {
await db.transaction(() async {
await db.createSomething(x, y, z);
final aThing = await db.getSomethingByX(x);
expect(aThing?.y, y);
});
}); I'd like to end each test with a rollback, how do I do that? |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 5 replies
-
I guess an alternative is to have each test spawn its own exclusive in-memory database, but my intuition is that it's not going to scale well. |
Beta Was this translation helpful? Give feedback.
-
Or can I do that instead? // setUpAll to create an in-memory database
// tearDownAll to db.close()
test('something', () async {
final transactionExecutor = db.executor.beginTransaction();
await db.createSomething(x, y, z);
final aThing = await db.getSomethingByX(x);
expect(aThing?.y, y);
await transactionExecutor.rollback();
}); Then I suppose I could also move the begin/rollback code to setUp() and tearDown() functions? |
Beta Was this translation helpful? Give feedback.
-
I've just remembered that this is possible, I think it should clear all your concerns: void main() {
const name = 'file:tests_1?mode=memory&cache=shared'; // maybe use a unique name per file name
late Database _keepOpen;
late TodoDb db; // Your generated database class
setUpAll(() async {
final db = sqlite3.open(name, uri: true);
_keepOpen = sqlite3.open(name, uri: true);
final driftDb = TodoDb(NativeDatabase.opened(db));
await driftDb.customSelect('SELECT 1').get();
await driftDb.close();
});
tearDownAll(() => _keepOpen.dispose());
setUp(() async {
db = TodoDb(NativeDatabase.opened(sqlite3.open(name, uri: true)));
await db.customStatement('BEGIN TRANSACTION');
});
tearDown(() async {
await db.customStatement('COMMIT TRANSACTION');
await db.close();
});
test('first test', () async {
await db.customSelect('SELECT 1').get();
});
} Basically, this uses one single in-memory database that is created once (assuming that the schema migration is super expensive because e.g. you insert tons of data), but gives every test an independent connection to that database which also runs in a transaction so that different tests don't interfere with each other. This way, every test is sharing common data created in |
Beta Was this translation helpful? Give feedback.
I guess an alternative is to have each test spawn its own exclusive in-memory database, but my intuition is that it's not going to scale well.