I do have a Snackbar with a SnackbarAction which should open the default email app with a default subject and body on tap. I am wondering if there is somehow the possibility to verify if this really happens with some unit tests.
My Snackbar code looks like this:
SnackBar get snackbar =>
SnackBar(
content: Text(message),
action: SnackBarAction(
key: const Key('ErrorSnackbarAction'),
label: AppLocalizations
.of(_context)
.report,
onPressed: () async => await launch('mailto:[email protected]?subject=TestSubject&body=TestBody')));
I am already verifying the appearance which works fine:
group('ErrorSnackbar', () {
testWidgets('appearance test', (WidgetTester tester) async {
await tester.pumpWidget(_generateSnackbarApp());
await _showSnackbar(tester);
expect(find.text(userMessage), findsOneWidget);
expect(find.byWidgetPredicate((Widget widget) =>
widget is SnackBarAction && widget.label == 'Report'), findsOneWidget);
});
testWidgets('error report test', (WidgetTester tester) async {
await tester.pumpWidget(_generateSnackbarApp());
await _showSnackbar(tester);
tester.tap(find.byKey(errorSnackbarAction));
await tester.pump();
// how to verify that the default email app was opened
// with expected subject and body?
});
});
Short answer: You can't.
The launch with mailto
is handled by the OS of the device and is out of context of the flutter app.
As the flutter test package focuses on the flutter app, what happens on the OS is out of reach.
You can ensure that launchUrl
is called and the expected parameters were passed. The url_launcher
package should be tested. Therefore, we can expect that the email app opens, when we call launchUrl
with the mailto:
schema.
Here is a short introduction on how to test the url_launcher
package:
Add plugin_platform_interface
and url_launcher_platform_interface
to your dev dependencies:
dev_dependencies:
flutter_test:
sdk: flutter
plugin_platform_interface: any
url_launcher_platform_interface: any
Copy the mock_url_launcher_platform.dart
from the url_launcher
package: https://github.com/flutter/plugins/blob/main/packages/url_launcher/url_launcher/test/mocks/mock_url_launcher_platform.dart
Now you can test the launchUrl
calls like this:
void main() {
late MockUrlLauncher mock;
setUp(() {
mock = MockUrlLauncher();
UrlLauncherPlatform.instance = mock;
});
group('$Link', () {
testWidgets('calls url_launcher for external URLs with blank target',
(WidgetTester tester) async {
FollowLink? followLink;
await tester.pumpWidget(Link(
uri: Uri.parse('http://example.com/foobar'),
target: LinkTarget.blank,
builder: (BuildContext context, FollowLink? followLink2) {
followLink = followLink2;
return Container();
},
));
mock
..setLaunchExpectations(
url: 'http://example.com/foobar',
useSafariVC: false,
useWebView: false,
universalLinksOnly: false,
enableJavaScript: true,
enableDomStorage: true,
headers: <String, String>{},
webOnlyWindowName: null,
)
..setResponse(true);
await followLink!();
expect(mock.canLaunchCalled, isTrue);
expect(mock.launchCalled, isTrue);
});
});
}
Copied the test from https://github.com/flutter/plugins/blob/main/packages/url_launcher/url_launcher/test/link_test.dart
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With