如何对访问 Provider.of(context) 的小部件进行 Flutter 测试

Posted

技术标签:

【中文标题】如何对访问 Provider.of(context) 的小部件进行 Flutter 测试【英文标题】:How to do a Flutter Test for a widget that accesses Provider.of(context) 【发布时间】:2021-04-29 19:18:35 【问题描述】:

我想知道是否有人可以帮助我,我无法为我的 Flutter 项目的主页编写测试,因为它依赖于 Provider。

home_page.dart

Future<NewsModel> newsData = Provider.of<Future<NewsModel>>(context);

return FutureProvider(
  create: (context) => newsData,
  child: (newsData != null)
      ? Scaffold(
          body: SmartRefresher(
            controller: _refreshController,
            onRefresh: _refreshNews,
            onLoading: _onLoading,
            child: Consumer<NewsModel>(
              builder: (_, news, __) ...

main.dart

return MultiProvider(
  providers: [
    FutureProvider(create: (context) => geolocatorService.getlocation()),
    ProxyProvider<Position, Future<NewsModel>>(
      update: (context, position, news) 
        return (position != null) ? newsService.getNews() : null;
      ,
    ),

home_page_test.dart

testWidgets('Test the home screen', (WidgetTester tester) async 
HomePage homePage = new HomePage();

await tester.pumpWidget(
  makeWidgetTestable(
    child: homePage,
  ),
);

);

当我运行这个测试时,我收到以下错误,我真的很困惑,需要一些指导。我对 Flutter 相当有经验,但我是为需要外部依赖项的小部件编写小部件测试的新手。如果有人可以提供帮助,那就太好了。

错误:

The following ProviderNotFoundException was thrown building HomePage(dirty, dependencies [MediaQuery], state: _HomePageState#ce244): Error: Could not find the correct Provider<Future<NewsModel>> above this HomePage Widget

【问题讨论】:

【参考方案1】:

如果您使用主文件中的提供程序包装以下代码:

await tester.pumpWidget(
  makeWidgetTestable(
    child: homePage,
  ),
);

并把它变成:

testWidgets('Test the home screen', (WidgetTester tester) async 
//No longer need the following line
//HomePage homePage = new HomePage();

await tester.pumpWidget(
MultiProvider(
  providers: [
    FutureProvider(create: (context) => geolocatorService.getlocation()),
    ProxyProvider<Position, Future<NewsModel>>(
      update: (context, position, news) 
        return (position != null) ? newsService.getNews() : null;
      ,
    ),
    child: homePage,
  ),
);

【讨论】:

以上是关于如何对访问 Provider.of(context) 的小部件进行 Flutter 测试的主要内容,如果未能解决你的问题,请参考以下文章

Provider.of(context, listen: false) 是不是等同于 context.read()?

无法使用 Provider.of(context) 调用类方法

Flutter Provider:为啥在调用 Provider.of<Widget>(context) 时会出现此错误,如 tihis:

在dispose()方法内部调用带有Provider.of(context)的方法会导致“查找已停用的小部件的祖先是不安全的。”

如何在 Flutter 中正确重用 Provider

Flutter之跨组件状态共享Provider剖析