Home > Back-end >  Mock method of class under test in Dart
Mock method of class under test in Dart

Time:12-16

I have a helper class (in Dart) like below:

class AppInfoHelper {

  Future<String> getAppName() async {
    return getPackageInfo().then((info) => info.appName);
  }

  Future<String> getAppVersion() async {
    return getPackageInfo().then((info) => info.version);
  }

  Future<String> getBuildNumber() async {
    return getPackageInfo().then((info) => info.buildNumber);
  }
   Future<PackageInfo> getPackageInfo() async => PackageInfo.fromPlatform();
 
}

The responsibility of this class is providing app info. I'm using PackageInfo as one of the library. And for some reasons, I won't supply PackageInfo as constructor parameter.

How can I write proper unit test for this class? I'm not sure how to do stubbing since we getPackageInfo() method is coming from class under test itself.

Note: I'm using mockito (https://pub.dev/packages/mockito) and some reference mentioned about doing something like spy, but I don't think it's available from Dart/Flutter mockito.

CodePudding user response:

First, if you won't supply an instance of PackageInfo to your class then you'll have to create your own MockAppInfoHelper that will let you use a fake PackageInfo class.

Here's an example of implementation:

class MockAppInfoHelper extends AppInfoHelper {
  MockAppInfoHelper(this._packageInfo);

  final PackageInfo _packageInfo;

  @override
  Future<PackageInfo> getPackageInfo() async => _packageInfo;
}

And to mock a fake PackageInfo class you'll have to generate some mocks by adding the GenerateMocks annotation and running build_runner:

@GenerateMocks([PackageInfo])
import 'app_info_helper_test.mocks.dart'; // note that the name might change if your base file is not named app_info_helper_test

Now you can start to write your test method, here's an example of a test for getAppName:

void main() {
  group('AppInfoHelper', () {
    late MockPackageInfo mockPackageInfo;
    late MockAppInfoHelper mockAppInfoHelper;

    /// setUp is called before each test, it'll ensure that the mock is reset.
    setUp(() {
      mockPackageInfo = MockPackageInfo();
      mockAppInfoHelper = MockAppInfoHelper(mockPackageInfo);
    });

    test('test getAppName', () async {
      const testAppName = 'testAppName';

      // First arrange the mock to return the expected value.
      when(mockPackageInfo.appName).thenReturn(testAppName);

      // Then call the method you want to test.
      final result = await mockAppInfoHelper.getAppName();

      // Finally verify that the mock was called as expected.
      verify(mockPackageInfo.appName);
      expect(result, testAppName);
    });
  });
}
  • Related