在Flutter Widget测试中找不到BoxDecoration中的AssetImage

zqdjd7g9  于 7个月前  发布在  Flutter
关注(0)|答案(1)|浏览(59)

我试图创建小部件启动画面,显示应用程序加载时,显示本机启动画面。我创建了启动画面,一切似乎都很好,所以我决定创建小部件测试启动画面背景图像和屏幕上的单个文本。文本测试部分通过,但我有图像的问题。

Widget测试错误文本:

══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following TestFailure was thrown running a test:
Expected: exactly one matching node in the widget tree
  Actual: _WidgetTypeFinder:<zero widgets with type "Image" (ignoring offstage widgets)>
   Which: means none were found but one was expected

字符串

完整启动画面代码:

class SplashScreenPage extends StatefulWidget {
  const SplashScreenPage({Key? key}) : super(key: key);

  @override
  State<SplashScreenPage> createState() => _SplashScreenPageState();
}

class _SplashScreenPageState extends State<SplashScreenPage> {
  Timer? _timer;

  @override
  void initState() {
    _timer = Timer(const Duration(seconds: 4), () {
      Navigator.of(context).pushReplacementNamed(RoutingConst.defaultRoute);
    });
    super.initState();
  }

  @override
  void dispose() {
    _timer!.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
        Container(
          decoration: const BoxDecoration(
            image: DecorationImage(
              image: AssetImage("assets/images/background.png"),
              fit: BoxFit.cover,
            ),
          ),
        ),
        Padding(
          padding: const EdgeInsets.symmetric(horizontal: 16),
          child: Column(
            children: [
              const Spacer(),
              const Spacer(),
              const Spacer(),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Flexible(
                    child: Text(
                      "SPLASH SCREEN TEXT",
                      maxLines: 2,
                      overflow: TextOverflow.ellipsis,
                      textAlign: TextAlign.center,
                      style: GoogleFonts.inter(
                        color: Colors.white,
                        fontSize: 40,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                  ),
                ],
              ),
              const Spacer(),
            ],
          ),
        ),
      ]
      ),
    );
  }
}

小部件测试:

void main() {
  //
  // Setup
  //

  Widget createWidgetUnderTest() {
    return const MaterialApp(
      home: SplashScreenPage(),
    );
  }

  //
  // Testing
  //

  testWidgets(
    "Check if splash screen text shows up",
    (WidgetTester tester) async {
      await tester.pumpWidget(createWidgetUnderTest());
      expect(find.text("SPLASH SCREEN TEXT"), findsOneWidget);
    },
  );

  testWidgets(
    "Check if splash screen background shows up",
    (WidgetTester tester) async {
      await tester.pumpWidget(createWidgetUnderTest());
      expect(find.byType(Image), findsOneWidget);
    },
  );
}


文本测试通过,但是图像的那个失败了,我不知道为什么。我试过find.image(AssetImage(“asset-path”))但这也不起作用。试图把关键的容器举行框装饰,然后试图找到容器在测试中,它发现它,所以maybie我做错了在框装饰内找到图像,但我不知道如何找到它如果是这样的话

atmip9wb

atmip9wb1#

问题:

SplashScreenPage不包含实际的Image widget,因此测试中使用的查找器将无法找到Image小部件。

  • find.byType(Image)查找Image类型的Widget
  • find.image()查找ImageFadeInImage类型的Widget

将图像设置为Containerdecoration不会创建Image小部件,因此查找器不适合此测试。

解决方案:

使用find.byWidgetPredicate查找包含图像的实际Widget,在本例中为:Container,并添加检查以指定要查找的Container的属性。
下面是代码:

testWidgets(
    "Check if splash screen background shows up",
    (WidgetTester tester) async {
      await tester.pumpWidget(createWidgetUnderTest());

      final assetImageFinder = find.byWidgetPredicate(
        (Widget widget) {
          if (widget is Container) {
            final decoration = widget.decoration;

            if (decoration is BoxDecoration) {
              final image = decoration.image;

              if (image is DecorationImage) {
                final imageProvider = image.image;

                if (imageProvider is AssetImage) {
                  return imageProvider.assetName ==
                      "assets/images/background.png";
                }
              }
            }
          }

          return false;
        },
      );

      expect(assetImageFinder, findsOneWidget);
    },
  );

字符串

相关问题