Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FR: making mocking simple #336

Open
daadu opened this issue Mar 22, 2022 · 4 comments
Open

FR: making mocking simple #336

daadu opened this issue Mar 22, 2022 · 4 comments

Comments

@daadu
Copy link

daadu commented Mar 22, 2022

Something similar to how it is done in flutter with - TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(_methodChannel, _methodHandler);

Say for example, consider following dependecny graph my_app -> connectivity_plus -> connectivity_plus_linux -> dbus - know as a app developer - I would want to mock and test certain behaviour based on the result of where it is connected. It is possible to do this with other platform (like Android, iOS, mac which uses Flutter Platform Channels internally), but not with Linux as of now.

PS: I recently published mock_plugin - to simplify mocking "plugin" library for the end-application developer to mock plugin behaviours - turns out most plugins supporting Linux, uses dbus.dart - I would love to support that too with mock_plugin if there is a way to mock DBus client/channel/messages.

@daadu
Copy link
Author

daadu commented Mar 22, 2022

Providing a mechanism at dbus.dart level would allow by-passing "actual" calls for all plugins that uses dbus internally.

@robert-ancell
Copy link
Collaborator

@jpnurmi - you have more experience with this, WDYT?

@jpnurmi
Copy link
Contributor

jpnurmi commented Mar 23, 2022

I'm all for making it easier to test D-Bus-based Dart and Flutter apps and packages. 👍

Funny, we just discussed the other day about having to "pollute" code for mocking. 😄 Mocking out dbus.dart can be challenging even with direct access to DBusClient - in some cases, one needs to find a way to inject DBusRemoteObject mocks too. It's a pity that dbus.dart would need to be "polluted" with a mock-handler but as @daadu mentioned, sometimes the dependency is indirect and deeper under the hood...

P.S. @daadu, for that specific case, one could simply replace the ConnectivityPlatform instance with a fake (easier than a mock because of the instance token).

void main() {
  testWidgets('test with wifi', (tester) async {
    ConnectivityPlatform.instance =
        FakeConnectivityPlatform(ConnectivityResult.wifi);

    await tester.pumpWidget(...);
    await tester.pumpAndSettle();
    expect(foo, somethingThatExpectsWifi);
  });
}

class FakeConnectivityPlatform extends ConnectivityPlatform {
  FakeConnectivityPlatform(this._result);

  final ConnectivityResult _result;

  @override
  Future<ConnectivityResult> checkConnectivity() => Future.value(_result);

  @override
  Stream<ConnectivityResult> get onConnectivityChanged => const Stream.empty();
}

@daadu
Copy link
Author

daadu commented Mar 23, 2022

Almost forgot about this solution (setting Platform.instance), works for me as of now. Now that I think of this should be the prefered way of mocking plugins that use this (platform_interface) pattern, which almost all plugin that supports Linux does.

mocking actual messages/channels (MethodChannel or DBusClient) should only be preferred if platform_interface is not used by the plugin.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants