Generic mocker method generator for mockito or mocktail.
One mock
method to mock any class just like in the original mockito.
dev_dependencies:
mockor: ^1.0.0
Add a mocker.dart
file in your test folder and a mock method with a @GenerateMocker
annotation. Don't forget to import mockito here.
// This import is used by the generated mockor file to add Mockito's `@GenerateMocks` annotation.
// This need to be added manually.
import 'package:mockito/mockor.dart';
// <file_name>.mocks.dart will be generated by Mockito which contain all the generated mocks.
// This needs to be added manually.
import 'example.mocks.dart';
import 'package:mockor/mockor.dart';
part 'example.mockor.dart';
abstract class ExampleUseCase {
int example(int i);
}
abstract class ExampleUseCase2 {
void example2();
}
@GenerateMocker([
ExampleUseCase,
ExampleUseCase2,
])
T mock<T extends Object>({bool relaxed = false}) => _$mock<T>(relaxed: relaxed);
import '../../mocker.dart';
void main() {
late ExampleUseCase exampleUseCase;
late ExampleUseCase2 exampleUseCase2;
setUp(() {
// this will return [MockExampleUseCase]
exampleUseCase = mock();
exampleUseCase2 = mock();
});
}
for more info check out the example module.
Getting Started using mocktail
// This import will be used for generating the mocks.
// This needs to be added manually.
import 'package:mocktail/mocktail.dart';
import 'package:mockor/mockor.dart';
part 'mocker.mockor.dart';
@GenerateMocker.mocktail(
[
ExampleUseCase,
ExampleUseCase2,
],
// optionally generate relaxedVoid parameter which prevents missing stub errors for `void` and `Future<void>`
generateRelaxedVoidParameter: true,
// optionally generate fallback values for non null params to use `any()`
generateMocktailFallbackValues: GenerateMocktailFallbackValues(
[ExampleModel],
// optionally register a mock class for all the non primitive parameters of all the methods in each class of [GenerateMocker.types] automatically.
autoDetect: true,
),
)
T mock<T extends Object>({bool relaxed = false, bool? relaxedVoid}) =>
_$_mock<T>(relaxed: relaxed, relaxedVoid: relaxedVoid);
//define a global register fallback values method
void registerFallbackValuesAll() {
_$registerFallbackValues();
}
import 'dart:async';
import 'package:flutter_test/flutter_test.dart';
import 'mocker.dart';
Future<void> testExecutable(FutureOr<void> Function() testMain) async {
// this will be executed before the main function of any test file in the test folder.
setUpAll(() {
registerFallbackValuesAll();
});
await testMain();
}
The _$mock<T>()
method takes in an optional bool
parameter named relaxed
.
If it's false
, throwOnMissingStub
is called on the Mock
object with so that you get exceptions when you try to call a method that is not stubbed.
However if it's true
, a TypeError
is thrown when the method has a non null return type.
On nullable return types, null is returned for missing stubs.
It is true
by default for mocktail
It is false
by default for mockito
T mock<T extends Object>({bool relaxed = false}) => _$mock<T>(relaxed: relaxed);
final myService = mock<MyService>(relaxed: true);
when(myService.doSomethingElse()).thenReturn(true);
myService.doSomething(); // this will throw an exception
myService.doSomethingElse(); // this will not throw an exception
For more info check out the example module.
- Renaming the class will not break tests.
- Find usages will not miss anything
- Never have to import/depend on mocks directly
An optional relaxed
parameter is added to the generated _$mock
method.
When set to true
, null
is returned for missing nullable stubs. And TypeError
for non null missing stubs.
This is further explained above.
Even though Mocktail was created to avoid code generation, here code generation is required but only for the one file with the generic mock function. There's no dependency to generated code in any of your tests. And each mock class is only 1 line long.
The generated mock classes are private so cannot be imported. Simply call the global mock
method.
This makes it easier for all developers to follow consistent code conventions.
An annoying drawback of mocktail is that you need to register fallback values if you want to call the any()
function on them.
With Mockor, you can generate a registerFallbackValues
function where you can either specify the types manually or let the generator auto detect them.
Check getting started above for more info.
An optional relaxed
parameter is added to the generated _$mock
method.
When set to true
, null
is returned for missing nullable stubs. And TypeError
for non null missing stubs.
This is further explained above.
An optional relaxed
parameter is added to the generated _$mock
method.
When set to true
, unstubbed void
- and Future<void>
methods don't throw errors.
in the root of your project add an analysis_options.yaml
with following content:
analyzer:
exclude:
- '**/*.mocks.dart' # Mockito @GenerateMocks
The mocker method only supports returning a mock instance for it's base type.
To be able to use of any
, you need the mocked type and not the base type.
An asMock
extension function is generated for this purpose.
extension ExampleUseCaseAsMockExtension on ExampleUseCase {
MockExampleUseCase asMock() => this as MockExampleUseCase;
}
Then in your test:
abstract class ExampleUseCase {
int example(int i);
}
final ExampleUseCase useCase = mock();
// asMock required becuase int i is non null and `any` returns null. the method is overriden with a nullable param in MockExampleUseCase.
when(useCase.asMock().example(any)).thenReturn(1)
Please read Mockito's Null Safety README for more info.