Unable to load asset SVG during widget testing

1,090

Just create fake AssetBundle and wrap the whole app with it:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/svg.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';

class FakeAssetBundle extends Fake implements AssetBundle {
  final String svgStr = '''<svg viewBox="0 0 10 10"></svg>''';

  @override
  Future<String> loadString(String key, {bool cache = true}) async => svgStr;
}

void main() {
  testWidgets(
    'SvgPicture.asset passes',
    (WidgetTester tester) async {
      await tester.pumpWidget(DefaultAssetBundle(
        bundle: FakeAssetBundle(),
        child: MaterialApp(
          home: Scaffold(
            body: SvgPicture.asset('icons/pencil.svg'),
          ),
        ),
      ));
      await tester.pump();
    },
  );
}
Share:
1,090
Andrey Gritsay
Author by

Andrey Gritsay

Updated on December 31, 2022

Comments

  • Andrey Gritsay
    Andrey Gritsay over 1 year

    I want to do a widget test on some of my screens which includes SvgPicture widget, but I can't do it because it throws an exception.

    Code to reproduce the error:

    import 'package:flutter/material.dart';
    import 'package:flutter_svg/svg.dart';
    import 'package:flutter_test/flutter_test.dart';
    
    
    void main() {
      testWidgets(
        'SvgPicture.asset passes',
        (WidgetTester tester) async {
          await tester.pumpWidget(MaterialApp(
            home: Scaffold(
              body: SvgPicture.asset('icons/pencil.svg'),
            ),
          ));
          await tester.pump();
        },
      );
    }
    

    Result of execution:

    ══╡ EXCEPTION CAUGHT BY SVG ╞═══════════════════════════════════════════════════════════════════════
    The following assertion was thrown resolving a single-frame picture stream:
    Unable to load asset: icons/pencil.svg
    
    When the exception was thrown, this was the stack:
    #0      PlatformAssetBundle.load (package:flutter/src/services/asset_bundle.dart:224:7)
    <asynchronous suspension>
    <asynchronous suspension>
    (elided one frame from package:stack_trace)
    ...
    
    Picture provider: ExactAssetPicture(name: "icons/pencil.svg", bundle: null, colorFilter: null)
    Picture key: AssetBundlePictureKey(bundle: PlatformAssetBundle#c2c00(), name: "icons/pencil.svg",
      colorFilter: null)
    ════════════════════════════════════════════════════════════════════════════════════════════════════
    

    How do I pass the test?

  • Rudolf J
    Rudolf J over 1 year
    And how should we do this for an integration test where we just run the main() function in the test?
  • Rudolf J
    Rudolf J over 1 year
    And I'd like the real assets to display
  • Chris
    Chris over 1 year
    How to do the same for PNG?