Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Write tests for Provider
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Hiroki Matsue
May 22, 2019
Technology
870
4
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Write tests for Provider
"Flutter Meetup Tokyo #9"でのLT資料です。
https://flutter-jp.connpass.com/event/126419/
Hiroki Matsue
May 22, 2019
More Decks by Hiroki Matsue
See All by Hiroki Matsue
Getting Screenshots Automatically in Flutter
matsue
2
570
Optimize Flutter Workflow on Bitrise
matsue
2
1.3k
ややcomplexなBLoCへの対応
matsue
2
830
Flutterアプリの難読化とエラーレポート(iOS)
matsue
2
2.2k
いまさらだけど「良い通知」について考えてみた
matsue
4
11k
リテンション率を2倍にするための2つの視点
matsue
0
3.6k
リソースを効率的に使うためのバックログ活用事例
matsue
1
520
ローディング時のより良いUIの実装
matsue
2
2k
カウルにおけるElasiticsearchの導入と実例
matsue
0
960
Other Decks in Technology
See All in Technology
LiDAR SLAMの実装とセンサ融合 ~Lie群からContinuous-Time LIOまで~
naokiakai
1
1k
product engineering with qa
nealle
0
150
Why is RC4 still being used?
tamaiyutaro
0
310
実装だけじゃない! CCA-F取得エンジニアが教えるClaude Code開発プロセス活用術
diggymo
2
450
依頼文化をやめる日 EM視点で語るPlatform EngineeringとInclusive SRE / Discussing Platform Engineering and Inclusive SRE from an EM's Perspective
shin1988
4
4.3k
最近評価が難しくなった
maroon8021
0
260
SRE依存からの脱却 運用を開 発チームへ移す、 フルサイ クル開 発体制の実践
joooee0000
0
1.9k
AWS Summit の片隅で、体育座りしながらコミュニティがにぎわう理由を考えた
k_adachi_01
2
360
AIで政治は変わるのか? — 中高生と考えたAI時代の民主主義(東海高校サタデープログラム)
eitarosuda
0
400
知見・人・API・DB・予算 ─ ナイナイ尽くしだった人事データ整備 with dbt、5年間の学び
ken6377
1
170
型は壁、Rustでもバグを直すな、表現できなくせよ
nwiizo
12
1.8k
美しいコードを書くためにF#を学んでみた話
yud0uhu
1
360
Featured
See All Featured
Designing for humans not robots
tammielis
254
26k
Typedesign – Prime Four
hannesfritz
42
3.1k
Everyday Curiosity
cassininazir
0
250
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
590
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
300
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
Test your architecture with Archunit
thirion
1
2.3k
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
220
HTML-Aware ERB: The Path to Reactive Rendering @ RubyCon 2026, Rimini, Italy
marcoroth
2
310
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
2
1.6k
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
630
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.8k
Transcript
Write tests for Provider Hiroki Matsue (@macs_6) May 22th, 2019
Flutter Meetup Tokyo #9
This talk is about How to test Provider classes
What is Provider Google I/O 2019ͷFlutterʹ͓͚Δ࣮ફతͳstateཧͷൃදͰ հ͞Εͨύοέʔδ Pragmatic State Management
in Flutter (Google I/O'19) https://youtu.be/d_m5csmrf7I
A dependency injection system built with widgets for widgets. provider
is mostly syntax sugar for InheritedWidget, to make common use-cases straightforward. https://github.com/rrousselGit/provider • ΄΅InheritedWidgetͷγϯλοΫεγϡΨʔ • BLoCΛ͏࣌ʹࣗલͰProvider૬ͷͷΛ࣮͍ͯͨ͠ ͣ
BLoC͚ʹॻ͍͍ͯͨInheritedWidgetΛͬͨProvider class CartProvider extends InheritedWidget { final CartBloc cartBloc; CartProvider({
Key key, CartBloc cartBloc, Widget child, }) : cartBloc = cartBloc ?? CartBloc(), super(key: key, child: child); @override bool updateShouldNotify(InheritedWidget oldWidget) => true; static CartBloc of(BuildContext context) => (context.inheritFromWidgetOfExactType(CartProvider) as CartProvider) .cartBloc; } final cartBloc = CartProvider.of(context); https://github.com/filiph/stateexperiments/blob/19c321bbc62ac10855751124e3ea9701e583d6ea/shared/lib/src/bloc/cartprovider.dart
ProviderύοέʔδΛ͏ͱ͜͏ͳΔ Provider<ExampleBloc>( builder: (_) => ExampleBloc(), dispose: (_, value) =>
value.dispose(), child: ExampleBloc(), ); final bloc = Provider.of<ExampleBloc>(context)
શ෦BLoCͰॻͭ͘ΓͳΒbloc_providerύοέʔδ bloc is disposed automatically https://pub.dev/packages/bloc_provider BlocProvider<ExampleBloc>( creator: (_context, _bag)
=> ExampleBloc(), child: Example(), )
ProviderΛ͏ͱ • streamRxDartΛΘͣʹෳWidgetؒͷstateΛཧͰ͖ ֶͯशίετ͕͍ • ඞཁʹԠͯ͡BLoCಋೖͰ͖Δ
How to write tests?
class Counter with ChangeNotifier { Counter( this._number, ); factory Counter.withInitialValues({
int number = 0, }) { return Counter(number); } int _number; int get number => _number; void increment() { _number++; notifyListeners(); } }
notifyListeners()Λແࢹ͢ΔͳΒ test('increment', () { final counter = Counter.withInitialValues(); expect(counter.number, 0);
counter.increment(); expect(counter.number, 1); });
֤छύοέʔδͷςετͰtestWidgetsΛ͍ͬͯΔ
UIςετͱͯ͠ widgetΛςετ͚ʹॳظԽ͢Δ
testWidgets("increment", (tester) async { final key = GlobalKey(); await tester.pumpWidget(
ChangeNotifierProvider( builder: (context) => Counter.withInitialValues(), child: MaterialApp( home: Consumer<Counter>( builder: (context, counter, child) => FlatButton( key: key, onPressed: () => counter.increment(), child: Text(counter.number.toString())), ), ), ), ); expect(find.text('0'), findsOneWidget); expect(find.text('1'), findsNothing); await tester.tap(find.byKey(key)); await tester.pumpAndSettle(); expect(find.text('0'), findsNothing); expect(find.text('1'), findsOneWidget); });
֤छύοέʔδͷςετͰݟΒΕΔ
͍ճ͢widgetΛอଘ͓ͯ͘͠ final tree = ChangeNotifierProvider( builder: (context) => Counter.withInitialValues(), child:
MaterialApp( home: Consumer<Counter>( builder: (context, counter, child) => FlatButton( key: key, onPressed: () => counter.increment(), child: Text(counter.number.toString())), ), ), );
ʹରͯ͠ݕূΛߦ͏ testWidgets("increment", (tester) async { final key = GlobalKey(); int
number; await tester.pumpWidget( ChangeNotifierProvider( builder: (context) => Counter.withInitialValues(), child: MaterialApp( home: Consumer<Counter>(builder: (context, counter, child) { number = counter.number; return FlatButton( key: key, onPressed: () => counter.increment(), child: Container(), ); }), ), ), ); });
notifierΛcontext͔Βऔಘͯ͠ݕূ͢Δ testWidgets('works with MultiProvider', (tester) async { final key =
GlobalKey(); var notifier = ChangeNotifier(); await tester.pumpWidget(MultiProvider( providers: [ ChangeNotifierProvider.value(notifier: notifier), ], child: Container(key: key), )); expect(Provider.of<ChangeNotifier>(key.currentContext), notifier); }); https://github.com/rrousselGit/provider/blob/fe778651565f7563dc4a1b2afb513119c5424761/test/changenotifierprovider_test.dart#L11-
·ͱΊ • testWidgets Λͬͯςετॻ͘ • ֤छύοέʔδΛݟΔͱςετͷهड़ΛݮΒ͕͢৭ʑݟ ΒΕΔ • ରͷwidgetΛ͍ճ͢ •
มʹೖΕͯݕূ͢Δ • notifierΛऔಘ͢Δ
References • Developer Questͷςετ: https://github.com/2d-inc/ developerquest/blob/master/test/worldtest.dart • Providerύοέʔδͷςετ: https://github.com/ rrousselGit/provider/blob/
fe778651565f7563dc4a1b2afb513119c5424761/test/ changenotifierprovider_test.dart • FlutterຊମͷChangeNotifierςετ: https://github.com/ flutter/flutter/blob/
Thanks