How to test a method that uses package_info in Flutter?
Asked Answered
A

4

13

I am writing a Flutter plugin that checks the Play Store or App Store to see if the app needs to be updated. I'm using the package_info package to determine the version of the app that the user has. My code looks like this:

getVersionStatus() {
    PackageInfo packageInfo = await PackageInfo.fromPlatform();
    localVersion = packageInfo.version;
    ...
}

I want to test this method, but if it run it as a unit test the fromPlatform call just hangs and times out the test. Is there a more elegant way to solve this than passing in a testing boolean? I.e:

if (testing) {
    PackageInfo packageInfo = await PackageInfo.fromPlatform();
    localVersion = packageInfo.version;
} else {
    localVersion = '0.0.0'
}

Should the package_info package provide a way to catch errors? Is there a way to tell if the method is being run by a test?

Ashmore answered 12/1, 2019 at 18:8 Comment(1)
There are methods on MethodChannel to register mock callbacks to send mock returnsHallucinatory
C
14

Like Günter said, you can mock PackageInfo by installing a mock method handler in the MethodChannel for the plugin:

void packageInfoMock() {
  const MethodChannel('plugins.flutter.io/package_info').setMockMethodCallHandler((MethodCall methodCall) async {
    if (methodCall.method == 'getAll') {
      return <String, dynamic>{
        'appName': 'ABC',  // <--- set initial values here
        'packageName': 'A.B.C',  // <--- set initial values here
        'version': '1.0.0',  // <--- set initial values here
        'buildNumber': ''  // <--- set initial values here
      };
    }
    return null;
  });
}
Cause answered 1/3, 2019 at 12:38 Comment(3)
Oh I didn't consider overwriting plugin channels, that works! Thanks.Ashmore
Don't forget to import 'package:flutter/services.dart';Ouphe
please update this link, currently has error: Page Not Found.Shoat
Y
10
PackageInfo.setMockInitialValues(appName: "abc", packageName: "com.example.example", version: "1.0", buildNumber: "2", buildSignature: "buildSignature");
Yorktown answered 20/3, 2022 at 15:20 Comment(1)
See "Explaining entirely code-based answers". While this might be technically correct, it doesn't explain why it solves the problem or should be the selected answer. We should educate along with helping solve the problem.Sams
A
0

I delegated the PackageInfo access to a repository object. This repo then is easy to mock. This also works for package_info_plus.

Auriferous answered 17/2, 2022 at 10:12 Comment(1)
Can you please share a complete example of how to test function using package device_info_plus.Stannum
A
0

We had below code to populate the version info in App's About section

final packageInfo = await PackageInfo.fromPlatform();
final versionName = packageInfo.version;
final buildNumber = packageInfo.buildNumber;

To support the widget test, below is the code to mock the PackageInfo

PackageInfo.setMockInitialValues(
      appName: 'test',
      packageName: 'com.test.test',
      version: '1',
      buildNumber: '123',
      buildSignature: 'test',
    );

this comes from package_info_plus.dart which provides the implementation of PackageIngo, and the method setMockInitialValues is added to support the testing.

@visibleForTesting
  static void setMockInitialValues({

For PackageInfo implmentation we have to include below dependency in pubspec.yaml

package_info_plus: ^5.0.1
Affine answered 15/4 at 20:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.