Created
November 25, 2018 21:46
-
-
Save brianegan/1c3d5246cf45c90e5e6cba6926839e6e to your computer and use it in GitHub Desktop.
Search Screen Test using a Mock Bloc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
import 'package:flutter_test/flutter_test.dart'; | |
import 'package:github_search/github_api.dart'; | |
import 'package:github_search/search_bloc.dart'; | |
import 'package:github_search/search_empty_view.dart'; | |
import 'package:github_search/search_error_view.dart'; | |
import 'package:github_search/search_intro_view.dart'; | |
import 'package:github_search/search_loading_view.dart'; | |
import 'package:github_search/search_result_view.dart'; | |
import 'package:github_search/search_screen.dart'; | |
import 'package:github_search/search_state.dart'; | |
import 'package:image_test_utils/image_test_utils.dart'; | |
import 'package:mockito/mockito.dart'; | |
import 'package:rxdart/rxdart.dart'; | |
class MockSearchBloc extends Mock implements SearchBloc {} | |
class MockOnTextChanged extends Mock implements Sink<String> {} | |
void main() { | |
group('Search Screen', () { | |
final findIntro = find.byType(SearchIntroView); | |
final findLoading = find.byType(SearchLoadingView); | |
final findEmpty = find.byType(SearchEmptyView); | |
final findError = find.byType(SearchErrorView); | |
final findPopulated = find.byType(SearchResultView); | |
testWidgets('initially displays an intro screen', (tester) async { | |
final bloc = MockSearchBloc(); | |
final screen = SearchScreen(initBloc: () => bloc); | |
when(bloc.onTextChanged).thenAnswer((_) => PublishSubject<String>()); | |
when(bloc.state).thenAnswer((_) => BehaviorSubject()); | |
await tester.pumpWidget(MaterialApp(home: screen)); | |
expect(findIntro, findsOneWidget); | |
}); | |
testWidgets('displays a loading screen', (tester) async { | |
final bloc = MockSearchBloc(); | |
final screen = SearchScreen(initBloc: () => bloc); | |
when(bloc.onTextChanged).thenAnswer((_) => PublishSubject<String>()); | |
when(bloc.state) | |
.thenAnswer((_) => BehaviorSubject(seedValue: SearchLoading())); | |
await tester.pumpWidget(MaterialApp(home: screen)); | |
expect(findLoading, findsOneWidget); | |
}); | |
testWidgets('transitions from one state to another', (tester) async { | |
final bloc = MockSearchBloc(); | |
final screen = SearchScreen(initBloc: () => bloc); | |
final subject = BehaviorSubject<SearchState>(); | |
when(bloc.onTextChanged).thenAnswer((_) => PublishSubject<String>()); | |
when(bloc.state).thenAnswer((_) => subject); | |
await tester.pumpWidget(MaterialApp(home: screen)); | |
expect(findIntro, findsOneWidget); | |
subject.add(SearchError()); | |
await tester.pumpAndSettle(); | |
expect(findError, findsOneWidget); | |
}); | |
testWidgets('displays an empty screen', (tester) async { | |
final bloc = MockSearchBloc(); | |
final screen = SearchScreen(initBloc: () => bloc); | |
when(bloc.onTextChanged).thenAnswer((_) => PublishSubject<String>()); | |
when(bloc.state) | |
.thenAnswer((_) => BehaviorSubject(seedValue: SearchEmpty())); | |
await tester.pumpWidget(MaterialApp(home: screen)); | |
expect(findEmpty, findsOneWidget); | |
}); | |
testWidgets('displays an error screen', (tester) async { | |
final bloc = MockSearchBloc(); | |
final screen = SearchScreen(initBloc: () => bloc); | |
when(bloc.onTextChanged).thenAnswer((_) => PublishSubject<String>()); | |
when(bloc.state) | |
.thenAnswer((_) => BehaviorSubject(seedValue: SearchError())); | |
await tester.pumpWidget(MaterialApp(home: screen)); | |
expect(findError, findsOneWidget); | |
}); | |
testWidgets('displays a list of results', (tester) async { | |
provideMockedNetworkImages(() async { | |
final bloc = MockSearchBloc(); | |
final screen = SearchScreen(initBloc: () => bloc); | |
when(bloc.onTextChanged).thenAnswer((_) => PublishSubject<String>()); | |
when(bloc.state).thenAnswer((_) => BehaviorSubject( | |
seedValue: SearchPopulated( | |
SearchResult([SearchResultItem('A', 'B', 'C')])))); | |
await tester.pumpWidget(MaterialApp(home: screen)); | |
expect(findPopulated, findsOneWidget); | |
}); | |
}); | |
testWidgets('sends text to bloc when the user types', (tester) async { | |
final bloc = MockSearchBloc(); | |
final screen = SearchScreen(initBloc: () => bloc); | |
final onTextChanged = MockOnTextChanged(); | |
when(bloc.onTextChanged).thenAnswer((_) => onTextChanged); | |
when(bloc.state).thenAnswer((_) => BehaviorSubject()); | |
await tester.pumpWidget(MaterialApp(home: screen)); | |
await tester.enterText(find.byType(TextField), 'A'); | |
verify(onTextChanged.add('A')); | |
}); | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment