How to mock a static getter's return value in Dart or Flutter?
Asked Answered
I

2

6

I would like to figure out how to modify the return value of a static getter for my unit tests in Flutter and Dart.

I'm unit testing a simple function:

  Future<bool> exampleFunc() async {
    if (Platform.isIOS) {
      // Do some iOS-specific things
      return false;
    } else if (Platform.isAndroid) {
      // Do some Android-specific things
      return true; // just as an example
    }
    throw 'Unexpected platform';
  }

And I would like to modify the return values of the static getters of a class: I would like to tweak Platform.isIOS and Platform.isAndroid return value for the different test cases.

Please note that I know of workarounds for this issue, for example, I could split the function into two functions (one for each platform), I could inject my own enum (or in this case, even a bool might work) that represents the supported platforms. In this example, I am actually going to do that, but I would like to know how to "modify" the return values of the Platform class's getters, because sometimes, you don't want to modify the signature of a function, as others might depend on it and yet, you still want to unit test the function.

Imam answered 4/1, 2020 at 15:23 Comment(0)
A
4

You should not mock classes that you don't own. Your unit test must be platform independent. On your case you should refactor your code to get rid of this dependency.

If you really wanna continue with this dependency at least depends on abstractions:

abstract class MyPlatform {
  bool isAndroid();
  bool isIos();
 }

class MyPlatformImp implements MyPlatform {
  @override
  bool isAndroid() => Platform.isAndroid;
  @override
  bool isIos() => Platform.isIOS;
 }

then you can mock MyPlatform on your uses.

This kind of variable you would test on Integration Tests https://flutter.dev/docs/cookbook/testing/integration/introduction

You can also create different tests for platforms using the onPlatform attribute of test() https://api.flutter.dev/flutter/test_api/test.html

Asarum answered 28/1, 2020 at 16:22 Comment(3)
The primary idea is not mock this static variables, but use specific platform tests using the onPlatform attribute of test methodsAsarum
Sorry about the last message, I started writing an answer, then realized I misread something. It seems that I accidentally sent the beginning of the message.Imam
Do you know if it's possible to mock static getters? I understand your POV, and to be honest, what I did is similar to what you recommended with the abstractions, see the last paragraph in my question ("Please note that I know of workarounds for this issue"...). I'm going to check how difficult it will be for my use-case to write the integration tests, thank you for the tip.Imam
W
0

I agree with Jhionan Santos, but there is an exception on You should not mock classes that you don't own.

On this topic, we could find a package that wrap the orgininal platform for testable. In my case I also need process to be mocked, so I also find a packakge.

https://pub.dev/packages/platform

https://pub.dev/packages/process

I recommend to use these packages, since they both own by google.

Wellintentioned answered 31/1, 2022 at 8:40 Comment(1)
Is there any sample code hot to mock it ?Fianna

© 2022 - 2024 — McMap. All rights reserved.