Use handwritten mocks instead of generating them

This commit is contained in:
Simon Binder 2021-01-06 19:36:50 +01:00
parent ab105cf77f
commit 5e8cd53bc6
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
3 changed files with 70 additions and 171 deletions

View File

@ -1,31 +1,11 @@
import 'dart:async';
// ignore: import_of_legacy_library_into_null_safe
import 'package:mockito/annotations.dart';
// ignore: import_of_legacy_library_into_null_safe
import 'package:mockito/mockito.dart';
import 'package:moor/moor.dart';
import 'package:moor/src/runtime/executor/stream_queries.dart';
import 'mocks.mocks.dart';
export 'mocks.mocks.dart';
@GenerateMocks(
[],
customMocks: [
MockSpec<QueryExecutor>(as: #MockExecutorInternal),
MockSpec<TransactionExecutor>(as: #MockTransactionsInternal),
MockSpec<StreamQueryStore>(
as: #MockStreamQueries, returnNullOnMissingStub: true)
],
)
// ignore: unused_element
void _pleaseGenerateMocks() {
// needed so that mockito generates classes for us.
}
class MockExecutor extends MockExecutorInternal {
final MockTransactionExecutor transactions = MockTransactionExecutor();
class MockExecutor extends Mock implements QueryExecutor {
late final MockTransactionExecutor transactions = MockTransactionExecutor();
final OpeningDetails? openingDetails;
bool _opened = false;
@ -55,10 +35,6 @@ class MockExecutor extends MockExecutorInternal {
assert(_opened);
return Future.value();
});
when(beginTransaction()).thenAnswer((_) {
assert(_opened);
return transactions;
});
when(ensureOpen(any)).thenAnswer((i) async {
if (!_opened && openingDetails != null) {
@ -76,26 +52,81 @@ class MockExecutor extends MockExecutorInternal {
_opened = false;
});
}
@override
SqlDialect get dialect =>
_nsm(Invocation.getter(#dialect), SqlDialect.sqlite);
@override
Future<bool> ensureOpen(QueryExecutorUser? user) =>
_nsm(Invocation.method(#ensureOpen, [user]), Future.value(true));
@override
Future<List<Map<String, Object?>>> runSelect(
String? statement, List<Object?>? args) =>
_nsm(Invocation.method(#runSelect, [statement, args]),
Future.value(<Map<String, Object?>>[]));
@override
Future<int> runInsert(String? statement, List<Object?>? args) =>
_nsm(Invocation.method(#runInsert, [statement, args]), Future.value(0));
@override
Future<int> runUpdate(String? statement, List<Object?>? args) =>
_nsm(Invocation.method(#runUpdate, [statement, args]), Future.value(0));
@override
Future<int> runDelete(String? statement, List<Object?>? args) =>
_nsm(Invocation.method(#runDelete, [statement, args]), Future.value(0));
@override
Future<void> runCustom(String? statement, [List<Object?>? args]) => _nsm(
Invocation.method(#runCustom, [statement, args]), Future.value(null));
@override
Future<void> runBatched(BatchedStatements? statements) =>
_nsm(Invocation.method(#runBatched, [statements]), Future.value(null));
@override
TransactionExecutor beginTransaction() =>
_nsm(Invocation.method(#beginTransaction, []), transactions) ??
transactions;
@override
Future<void> close() =>
_nsm(Invocation.method(#close, []), Future.value(null));
}
class MockTransactionExecutor extends MockTransactionsInternal {
class MockTransactionExecutor extends MockExecutor
implements TransactionExecutor {
MockTransactionExecutor() {
when(dialect).thenReturn(SqlDialect.sqlite);
when(runSelect(any, any)).thenAnswer((_) => Future.value([]));
when(runUpdate(any, any)).thenAnswer((_) => Future.value(0));
when(runDelete(any, any)).thenAnswer((_) => Future.value(0));
when(runInsert(any, any)).thenAnswer((_) => Future.value(0));
when(runCustom(any, any)).thenAnswer((_) => Future.value());
when(runBatched(any)).thenAnswer((_) => Future.value());
when(ensureOpen(any)).thenAnswer((_) => Future.value(true));
when(send()).thenAnswer((_) => Future.value(null));
when(rollback()).thenAnswer((_) => Future.value(null));
}
}
class MockStreamQueries extends Mock implements StreamQueryStore {
@override
Stream<T> registerStream<T>(QueryStreamFetcher<T>? fetcher) =>
_nsm(Invocation.method(#registerStream, [fetcher]), Stream<T>.empty());
@override
Stream<Null?> updatesForSync(TableUpdateQuery? query) => _nsm(
Invocation.method(#updatesForSync, [query]), const Stream<Never>.empty());
@override
void handleTableUpdates(Set<TableUpdate>? updates) =>
super.noSuchMethod(Invocation.method(#handleTableUpdates, [updates]));
@override
void markAsClosed(
QueryStream<dynamic>? stream, dynamic Function()? whenRemoved) =>
super.noSuchMethod(
Invocation.method(#markAsClosed, [stream, whenRemoved]));
@override
void markAsOpened(QueryStream<dynamic>? stream) =>
super.noSuchMethod(Invocation.method(#markAsOpened, [stream]));
@override
Future<void> close() =>
_nsm(Invocation.method(#close, []), Future.value(null));
}
DatabaseConnection createConnection(QueryExecutor executor,
[StreamQueryStore? streams]) {
return DatabaseConnection(
SqlTypeSystem.defaultInstance, executor, streams ?? StreamQueryStore());
}
extension on Mock {
T _nsm<T>(Invocation invocation, Object? returnValue) {
return noSuchMethod(invocation, returnValue) as T;
}
}

View File

@ -1,132 +0,0 @@
import 'package:mockito/mockito.dart' as _i1;
import 'package:moor/src/runtime/executor/executor.dart' as _i2;
import 'package:moor/src/runtime/query_builder/query_builder.dart' as _i3;
import 'dart:async' as _i4;
import 'package:moor/src/runtime/executor/stream_queries.dart' as _i5;
import 'package:moor/src/runtime/api/runtime_api.dart' as _i6;
class _FakeType extends _i1.Fake implements Type {}
class _FakeTransactionExecutor extends _i1.Fake
implements _i2.TransactionExecutor {}
/// A class which mocks [QueryExecutor].
///
/// See the documentation for Mockito's code generation for more information.
class MockExecutorInternal extends _i1.Mock implements _i2.QueryExecutor {
MockExecutorInternal() {
_i1.throwOnMissingStub(this);
}
_i3.SqlDialect get dialect =>
super.noSuchMethod(Invocation.getter(#dialect), _i3.SqlDialect.sqlite);
int get hashCode => super.noSuchMethod(Invocation.getter(#hashCode), 0);
Type get runtimeType =>
super.noSuchMethod(Invocation.getter(#runtimeType), _FakeType());
_i4.Future<bool> ensureOpen(_i2.QueryExecutorUser? user) =>
super.noSuchMethod(
Invocation.method(#ensureOpen, [user]), Future.value(false));
_i4.Future<List<Map<String, Object?>>> runSelect(
String? statement, List<Object?>? args) =>
super.noSuchMethod(Invocation.method(#runSelect, [statement, args]),
Future.value(<Map<String, Object?>>[]));
_i4.Future<int> runInsert(String? statement, List<Object?>? args) =>
super.noSuchMethod(
Invocation.method(#runInsert, [statement, args]), Future.value(0));
_i4.Future<int> runUpdate(String? statement, List<Object?>? args) =>
super.noSuchMethod(
Invocation.method(#runUpdate, [statement, args]), Future.value(0));
_i4.Future<int> runDelete(String? statement, List<Object?>? args) =>
super.noSuchMethod(
Invocation.method(#runDelete, [statement, args]), Future.value(0));
_i4.Future<void> runCustom(String? statement, [List<Object?>? args]) =>
super.noSuchMethod(
Invocation.method(#runCustom, [statement, args]), Future.value(null));
_i4.Future<void> runBatched(_i2.BatchedStatements? statements) =>
super.noSuchMethod(
Invocation.method(#runBatched, [statements]), Future.value(null));
_i2.TransactionExecutor beginTransaction() => super.noSuchMethod(
Invocation.method(#beginTransaction, []), _FakeTransactionExecutor());
_i4.Future<void> close() =>
super.noSuchMethod(Invocation.method(#close, []), Future.value(null));
bool operator ==(Object? other) =>
super.noSuchMethod(Invocation.method(#==, [other]), false);
String toString() => super.noSuchMethod(Invocation.method(#toString, []), '');
}
/// A class which mocks [TransactionExecutor].
///
/// See the documentation for Mockito's code generation for more information.
class MockTransactionsInternal extends _i1.Mock
implements _i2.TransactionExecutor {
MockTransactionsInternal() {
_i1.throwOnMissingStub(this);
}
_i3.SqlDialect get dialect =>
super.noSuchMethod(Invocation.getter(#dialect), _i3.SqlDialect.sqlite);
int get hashCode => super.noSuchMethod(Invocation.getter(#hashCode), 0);
Type get runtimeType =>
super.noSuchMethod(Invocation.getter(#runtimeType), _FakeType());
_i4.Future<void> send() =>
super.noSuchMethod(Invocation.method(#send, []), Future.value(null));
_i4.Future<void> rollback() =>
super.noSuchMethod(Invocation.method(#rollback, []), Future.value(null));
_i4.Future<bool> ensureOpen(_i2.QueryExecutorUser? user) =>
super.noSuchMethod(
Invocation.method(#ensureOpen, [user]), Future.value(false));
_i4.Future<List<Map<String, Object?>>> runSelect(
String? statement, List<Object?>? args) =>
super.noSuchMethod(Invocation.method(#runSelect, [statement, args]),
Future.value(<Map<String, Object?>>[]));
_i4.Future<int> runInsert(String? statement, List<Object?>? args) =>
super.noSuchMethod(
Invocation.method(#runInsert, [statement, args]), Future.value(0));
_i4.Future<int> runUpdate(String? statement, List<Object?>? args) =>
super.noSuchMethod(
Invocation.method(#runUpdate, [statement, args]), Future.value(0));
_i4.Future<int> runDelete(String? statement, List<Object?>? args) =>
super.noSuchMethod(
Invocation.method(#runDelete, [statement, args]), Future.value(0));
_i4.Future<void> runCustom(String? statement, [List<Object?>? args]) =>
super.noSuchMethod(
Invocation.method(#runCustom, [statement, args]), Future.value(null));
_i4.Future<void> runBatched(_i2.BatchedStatements? statements) =>
super.noSuchMethod(
Invocation.method(#runBatched, [statements]), Future.value(null));
_i2.TransactionExecutor beginTransaction() => super.noSuchMethod(
Invocation.method(#beginTransaction, []), _FakeTransactionExecutor());
_i4.Future<void> close() =>
super.noSuchMethod(Invocation.method(#close, []), Future.value(null));
bool operator ==(Object? other) =>
super.noSuchMethod(Invocation.method(#==, [other]), false);
String toString() => super.noSuchMethod(Invocation.method(#toString, []), '');
}
/// A class which mocks [StreamQueryStore].
///
/// See the documentation for Mockito's code generation for more information.
class MockStreamQueries extends _i1.Mock implements _i5.StreamQueryStore {
int get hashCode => super.noSuchMethod(Invocation.getter(#hashCode), 0);
Type get runtimeType =>
super.noSuchMethod(Invocation.getter(#runtimeType), _FakeType());
_i4.Stream<T> registerStream<T>(_i5.QueryStreamFetcher<T>? fetcher) =>
super.noSuchMethod(
Invocation.method(#registerStream, [fetcher]), Stream<T>.empty());
_i4.Stream<Null?> updatesForSync(_i6.TableUpdateQuery? query) =>
super.noSuchMethod(
Invocation.method(#updatesForSync, [query]), Stream<Null?>.empty());
void handleTableUpdates(Set<_i6.TableUpdate>? updates) =>
super.noSuchMethod(Invocation.method(#handleTableUpdates, [updates]));
void markAsClosed(
_i5.QueryStream<dynamic>? stream, dynamic Function()? whenRemoved) =>
super.noSuchMethod(
Invocation.method(#markAsClosed, [stream, whenRemoved]));
void markAsOpened(_i5.QueryStream<dynamic>? stream) =>
super.noSuchMethod(Invocation.method(#markAsOpened, [stream]));
_i4.Future<void> close() =>
super.noSuchMethod(Invocation.method(#close, []), Future.value(null));
bool operator ==(Object? other) =>
super.noSuchMethod(Invocation.method(#==, [other]), false);
String toString() => super.noSuchMethod(Invocation.method(#toString, []), '');
}

View File

@ -142,9 +142,9 @@ void main() {
verify(executor.transactions.rollback());
});
test('transactions notify about table udpates after completing', () async {
when(executor.transactions.runUpdate(any, any))
.thenAnswer((_) => Future.value(2));
test('transactions notify about table updates after completing', () async {
final transactions = executor.transactions;
when(transactions.runUpdate(any, any)).thenAnswer((_) => Future.value(2));
await db.transaction(() async {
await db