How to write tests with database that reads from file? Do I even need it? #1255
-
Hi, I have a table Code // In icon_colors_table.dart
class IconColors extends Table {
IntColumn get id => integer()();
TextColumn get name => text().customConstraint('NOT NULL UNIQUE')();
@override
Set<Column> get primaryKey => {id};
} I insert records to // In my_database.dart
@override
MigrationStrategy get migration {
return MigrationStrategy(
beforeOpen: (details) async {
await customStatement('PRAGMA foreign_keys = ON');
if (!details.wasCreated) return;
await batch(
(batch) {
batch.insertAll(
iconColors,
IconColorConstants.values.entries
.map((entry) => IconColorModel(id: entry.key, name: entry.value))
.toList(),
);
}
);
}
);
} When I want to add new colors to the app, I go to my // In icon_color_constants.dart
class IconColorConstants{
static const int version = 1; // Increment this to two when values changes
static const values = {
1: 'red',
2: 'orange',
3: 'green',
4: 'yellow',
};
} I am not showing the code because I have not written it yet, but in I want to test the logic of // In my_database_test.dart
void main() {
late MyDatabase db;
setUp(
db = MyDatabase(VmDatabase.memory());
);
} I am using
Question: How do I test this kind of logic? Or is there a better way to do this? I know this is kind of a long question, I also wrote this at night and my brain is not working well so reply if you need clarification or more code. Thanks for spending your time to read this. :D |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
I don't see anything wrong with it. I'm not fully sure why you need to store colors in a db if you have them as constants in your app, but your approach of writing data with version updates sounds reasonable to me. You could also use moor's
In You can use named in-memory databases to test this behavior. Unfortunately thee setup is a bit complicated, something like this should work: import 'dart:math';
import 'package:moor/fii.dart';
import 'package:sqlite3/sqlite3.dart';
import 'package:test/test.dart';
void main() {
late String connectionUri;
setUp(() {
connectionUri = 'file:mem${_randomString()}?mode=memory&cache=shared';
});
test('inserts new colors after a version upgrade', () async {
// open the database in a mode where it thinks items are at version 1 (how
// you do that is left up to you :D)
var db =
YourDatabaseClass(VmDatabase.opened(sqlite3.open(connectionUri, uri: true)));
// make sure the database is opened and migrations ran
await db.doWhenOpened((e) {});
await db.close();
// Create another database, this time with the new version constant
db = YourDatabaseClass(VmDatabase.opened(sqlite3.open(connectionUri, uri: true)));
// Ensure we have new colors...
await expectLater(
db.select(db.categories).get(), completion(hasLength(12)));
await db.close();
});
}
final Random _random = Random();
String _randomString() {
const charCodeLowerA = 97;
const charCodeLowerZ = 122;
const length = 16;
final buffer = StringBuffer();
for (var i = 0; i < length; i++) {
buffer.writeCharCode(
_random.nextInt(charCodeLowerZ - charCodeLowerA) + charCodeLowerA);
}
return buffer.toString();
} In the next moor version you can simplify this and work with a regular in-memory database: void main() {
late Database rawDb;
setUp(() {
rawDb = sqlite3.openInMemory();
});
tearDown(() {
rawDb.dispose();
});
test('inserts new colors after a version upgrade', () async {
// open the database in a mode where it thinks items are at version 1 (how
// you do that is left up to you :D)
var db =
e.Database(VmDatabase.opened(rawDb, closeUnderlyingOnClose: false));
// make sure the database is opened and migrations ran
await db.doWhenOpened((e) {});
await db.close();
// Create another database, this time with the new version constant
db = e.Database(VmDatabase.opened(rawDb, closeUnderlyingOnClose: false));
// Ensure we have new colors...
await expectLater(
db.select(db.categories).get(), completion(hasLength(12)));
await db.close();
});
} |
Beta Was this translation helpful? Give feedback.
I don't see anything wrong with it. I'm not fully sure why you need to store colors in a db if you have them as constants in your app, but your approach of writing data with version updates sounds reasonable to me. You could also use moor's
schemaVersion
for this instead of writing that information to a new table, but both approaches should be fine here.In
moor_generator
, we actually have something similar for verified schema migrations. You can find its implementation here, but it's likely more complicated than what you need.You …