繁体   English   中英

Dart/Flutter 小部件:获取使用 kIsWeb 的路径的测试覆盖率

[英]Dart/Flutter Widget : Get Test Coverage for path that uses kIsWeb

我想测试并涵盖使用 kIsWeb 的小部件的两个路径。 类看起来像这样:

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    if (kIsWeb) {
      return Text("I'm web");
    } else {
      return Text("I'm not web");
    }
  }
}

搜索了一段时间后,我在这里找到了一种测试方法: Testing kIsWeb constant in flutter

这是我写的测试类:

 class MockAppService extends Mock implements AppService {}
    
         void main() {
          final mockAppService = MockAppService();
          when(mockAppService.getkIsWeb())
              .thenAnswer((realInvocation) => true);
        
          testWidgets("add item", (WidgetTester tester) async {
            await tester.pumpWidget(MaterialApp(
              title: 'Flutter Demo',
              home: Scaffold(
                appBar: AppBar(
                  title: Text("title"),
                ),
                body: Center(
                  child: Text("message"),
                ),
              ),
            ));
            final PaymentPageState myWidgetState = tester.state(find.byType(PaymentPage));
            expect(find.byType(PaymentPage), findsOneWidget);
          });
        }

但我得到了错误

“Null”类型不是“bool”类型的子类型

我的 AppService 类和抽象类看起来像这样,

abstract class IAppService {
  bool getkIsWeb();
}

class AppService implements IAppService {
  bool getkIsWeb() {
    return kIsWeb;
  }
}

我是 Flutter 新手,很多东西都不知道。 请帮忙。

您找到的有关如何测试kIsWeb的解决方案应该可以工作,但您必须了解整个情况。

首先,这种方法背后的主要思想是,将决定应用程序是否在 Web 上运行的责任移出小部件,而不是直接在小部件的构建方法中使用kIsWeb

因此引入了一个名为IAppService的接口, AppService类实现了这个接口。 该接口并不是真正需要的,我将在我的示例中直接使用AppService类。

您的小部件应使用AppService实例并在其上调用getKIsWeb ,而不是直接使用kIsWeb常量。 有许多方法可以将实例提供给小部件。 使用构造函数参数是最简单的方法之一,但您将来可能想看看依赖注入或状态管理解决方案。

class MyWidget extends StatelessWidget {
  const MyWidget({Key? key, required this.appService}) : super(key: key);

  final AppService appService;

  @override
  Widget build(BuildContext context) {
    if (appService.getKIsWeb()) {
      return const Text('I\'m web');
    } else {
      return const Text('I\'m not web');
    }
  }
}

class AppService {
  bool getKIsWeb() {
    return kIsWeb;
  }
}

最后并非最不重要。 当你测试你的小部件时,你给它一个AppService类的模拟实现,它在调用getKIsWeb时返回 true 或 false,这取决于你想要测试的内容。

class MockAppService extends Mock implements AppService {}

void main() {
  testWidgets('Test web widget', (WidgetTester tester) async {
    final mockAppService = MockAppService();
    when(() => mockAppService.getKIsWeb()).thenReturn(true);

    await tester.pumpWidget(
      MaterialApp(
        title: 'Flutter Demo',
        home: Scaffold(
          body: MyWidget(
            appService: mockAppService,
          ),
        ),
      ),
    );

    final webTextFinder = find.text('I\'m web');
    expect(webTextFinder, findsOneWidget);
  });

  testWidgets('Test not web widget', (WidgetTester tester) async {
    final mockAppService = MockAppService();
    when(() => mockAppService.getKIsWeb()).thenReturn(false);

    await tester.pumpWidget(
      MaterialApp(
        title: 'Flutter Demo',
        home: Scaffold(
          body: MyWidget(
            appService: mockAppService,
          ),
        ),
      ),
    );

    final webTextFinder = find.text('I\'m not web');
    expect(webTextFinder, findsOneWidget);
  });
}

请注意,我在这里使用的是 Mocktail 而不是 Mockito。 但你应该明白这一点。

when(() => mockAppService.getKIsWeb()).thenReturn(false); 是定义模拟行为的 Mocktails 方式。 https://pub.dev/packages/mocktail

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM