Open ValentinVignal opened 2 years ago
I implemented the lib today and also couldn't see a way to properly test it, as we can't mock a static method. This is how I tested:
Create a "middleware" class. I called it ImageCropperService
:
import 'dart:io';
import 'package:image_cropper/image_cropper.dart';
/// This service allows us to test the ImageCropper library, as the `cropImage`
/// is a static method and couldn't be mocked.
class ImageCropperService {
// You can add other arguments from the original `cropImage` here as needed.
Future<File?> cropImage({required String sourcePath}) {
return ImageCropper.cropImage(
sourcePath: sourcePath,
);
}
}
Inject the ImageCropperService
in your code. In my case, I used get_it for it:
Future<void> cropImage() async {
File? croppedImage = await GetIt.I<ImageCropperService>().cropImage(sourcePath: pickedImage.path);
if (croppedImage == null) return;
doSomethingWithCroppedImage(croppedImage);
}
Remember to register the ImageCropperService before the application starts (in the main.dart
for example):
GetIt.I.registerFactory<ImageCropperService>(() => ImageCropperService());
Now in the test I used mocktail but you can also use mockito to mock the ImageCropperService
.
import 'package:mocktail/mocktail.dart' as mocktail;
// Create the mock class
class ImageCropperMock extends mocktail.Mock implements ImageCropperService {}
void main(){
ImageCropperService imageCropper;
setupAll((){
// Register the mock
imageCropper = ImageCropperMock();
GetIt.I.registerFactory<ImageCropperService>(() => imageCropper);
});
testWidget('description', (WidgetTester tester) async {
await pumpWidget(buildYourWidget());
// Do your test actions, then verify if ImageCropperService was properly called:
mocktail
.verify(() => imageCropper.cropImage(sourcePath: 'your_expected_path'))
.called(1);
});
}
I believe it should be better if the cropImage
wasn't static
though, so we could mock the ImageCropper
itself. If there is a better way, I will be glad to know it!
Thanks @daniloapr, I agree with you, we should get rid of using static function. I am going to work on it
I change cropImage
to instance method and release v1.5.0. @daniloapr Could you help me provide test codes for the plugin?
@daniloapr , I just migrate the plugin to federated plugins and publish it as v2.0.0-beta. If you want to provide unit test for the plugin, please consider to create PR on branch v2.
@hnvn I see your commit https://github.com/hnvn/flutter_image_cropper/commit/cd9843a8cc89fd003335036cb3e9b8f9f6ae10f5
May I suggest to do something like that instead?
class ImageCropper {
ImageCropper._();
static ImageCropper _instance = ImageCropper._();
static ImageCropper get instance => _instance;
@visibleForTesting
static ImageCropper set instance(ImageCropper instance) {
// So we can give a mock in the tests
_instance = instance;
}
// Not a static method anymore.
Future<File?> cropImage(/* ... */) {/* ... */}
}
And instead of doing
ImageCropper.cropImage();
or
ImageCropper().cropImage();
it will be
ImageCropper.instance.cropImage();
I have same approach in v2 branch, pls have a look at it: https://github.com/hnvn/flutter_image_cropper/blob/a6708c4d7e75d9b34763bd1aeb3fb9fe989235cd/image_cropper_platform_interface/lib/src/platform_interface/image_cropper_platform.dart#L34
Hello, I'm trying to write a test using your package, but I don't see any in this repository.
Could you add some so we can copy them?