Alvaro Lopez
Alvaro Lopez

Reputation: 1

How to mock AssetBundle loadString() call in test using mockito

`I prepared a test in Flutter using Mockito and build_runner to autogenerate the mocks, and the function I am trying to test is the following one:

  @override
  Future<List<Country>> loadCountries() async {
    try {
      _logger.debug('Loading countries...');

      String jsonString = await rootBundle.loadString('assets/json/countries.json');

      Map<String, dynamic> jsonData = json.decode(jsonString);

      List<dynamic> countryList = jsonData['countries'];

      List<Country> countries = countryList.map((json) => Country.fromJson(json)).toList();

      return countries;
    } catch (e) {
      _logger.error('Error loading countries: $e');
      rethrow;
    }
  }

I have a json called countries.json which contains a list of countries with this format:

{
    "name":"Afghanistan",
    "flag":"πŸ‡¦πŸ‡«",
    "isoCode":"AF",
    "dialCode":"+93"
},

There are more than 200 countries in the list. The test that I prepared for this function was this one:

@GenerateMocks([ILogger<CountryService>, AssetBundle])
void main() {
  TestWidgetsFlutterBinding.ensureInitialized();
  group('CountryService Tests', () {
    late CountryService countryService;
    final mockLogger = MockILogger<CountryService>();
    final mockBundle = MockAssetBundle();

    setUp(() {
      countryService = CountryService(mockLogger);
    });

    test('loadCountries success', () async {
      // Arrange
      const jsonString = '{"countries": [{"name": "United States", "dialCode": "+1", "isoCode": "US", "flag": "πŸ‡ΊπŸ‡Έ"}]}';
      final expectedCountries = [Country(name: 'United States', dialCode: '+1', isoCode: 'US', flag: 'πŸ‡ΊπŸ‡Έ')];
      when(mockBundle.loadString('assets/json/countries.json')).thenAnswer((_) async => jsonString);

      // Act
      final result = await countryService.loadCountries();

      // Assert
      expect(result, expectedCountries);
      verify(mockLogger.debug('Loading countries...')).called(1);
      verifyNever(mockLogger.error(any));
    });
  });
}

The problem is that when debugging the test, ILogger is properly mocked, but my AssetBundle is not mocked, so it is still loading the full list of +200 countries, instead of loading only the jsonString I am telling to answer when mockBundle.loadString() is called. I'd be very grateful if anyone could help me, or have a brilliant idea to test this function. Thank you. `

Upvotes: 0

Views: 56

Answers (0)

Related Questions