Skip to content

Commit

Permalink
chore: write test for survey completed screen (#30)
Browse files Browse the repository at this point in the history
  • Loading branch information
markgravity committed May 17, 2021
1 parent c36a0f6 commit 5203f4c
Show file tree
Hide file tree
Showing 12 changed files with 751 additions and 348 deletions.
699 changes: 356 additions & 343 deletions coverage/lcov.info

Large diffs are not rendered by default.

7 changes: 2 additions & 5 deletions lib/gen/assets.gen.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions lib/modules/survey_completed/components/content.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class Content extends StatelessWidget {
children: [
Lottie.asset(
Assets.animations.surveyCompleted,
key: SurveyCompletedView.lottieKey,
repeat: false,
controller: state._animationController,
onLoaded: (composition) {
Expand Down
2 changes: 2 additions & 0 deletions lib/modules/survey_completed/survey_completed_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ abstract class SurveyCompletedViewDelegate {
}

abstract class SurveyCompletedView extends View<SurveyCompletedViewDelegate> {
static const lottieKey = Key("survey_completed_view_lottie");

void setOutro(SurveyQuestionInfo outro);

void beginAnimation();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:quick_test/quick_test.dart';
import 'package:survey/models/survey_question_info.dart';
import 'package:survey/modules/survey_completed/survey_completed_module.dart';
import 'package:survey/services/locator/locator_service.dart';
import '../../helpers/behavior_subject_generator.dart';
import 'survey_completed_interactor_test.mocks.dart';

@GenerateMocks([SurveyCompletedInteractorDelegate])
void main() {
describe("a SurveyCompleted interactor", () {
late SurveyCompletedInteractor interactor;
late MockSurveyCompletedInteractorDelegate delegate;
late BehaviorSubjectGenerator generator;
final outro = SurveyQuestionInfo();
beforeEach(() {
generator = BehaviorSubjectGenerator();

delegate = MockSurveyCompletedInteractorDelegate();

interactor = SurveyCompletedInteractorImpl();
interactor.arguments = SurveyCompletedArguments(outro: outro);
interactor.delegate = delegate;
});

it("returns correct outro", () {
expect(interactor.outro, outro);
});
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Mocks generated by Mockito 5.0.7 from annotations
// in survey/test/modules/survey_completed/survey_completed_interactor_test.dart.
// Do not manually edit this file.

import 'package:mockito/mockito.dart' as _i1;
import 'package:survey/modules/survey_completed/survey_completed_module.dart'
as _i2;

// ignore_for_file: comment_references
// ignore_for_file: unnecessary_parenthesis

// ignore_for_file: prefer_const_constructors

// ignore_for_file: avoid_redundant_argument_values

/// A class which mocks [SurveyCompletedInteractorDelegate].
///
/// See the documentation for Mockito's code generation for more information.
class MockSurveyCompletedInteractorDelegate extends _i1.Mock
implements _i2.SurveyCompletedInteractorDelegate {
MockSurveyCompletedInteractorDelegate() {
_i1.throwOnMissingStub(this);
}
}
27 changes: 27 additions & 0 deletions test/modules/survey_completed/survey_completed_module_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:quick_test/quick_test.dart';
import 'package:survey/modules/survey_completed/survey_completed_module.dart';

import '../../mocks/build_context.dart';

void main() {
describe("a SurveyCompleted module", () {
late SurveyCompletedModule module;
beforeEach(() {
module = SurveyCompletedModule();
});

describe("it's build is called", () {
late Widget widget;

beforeEach(() {
widget = module.build(MockBuildContext());
});

it("returns SurveyCompletedViewImpl", () {
expect(widget, isA<SurveyCompletedViewImpl>());
});
});
});
}
67 changes: 67 additions & 0 deletions test/modules/survey_completed/survey_completed_presenter_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:quick_test/quick_test.dart';
import 'package:survey/models/survey_question_info.dart';
import 'package:survey/modules/survey_completed/survey_completed_module.dart';

import '../../mocks/build_context.dart';
import 'survey_completed_presenter_test.mocks.dart';

@GenerateMocks(
[SurveyCompletedView, SurveyCompletedRouter, SurveyCompletedInteractor])
void main() {
describe("a SurveyCompleted presenter", () {
late SurveyCompletedPresenterImpl presenter;
late MockSurveyCompletedView view;
late MockSurveyCompletedRouter router;
late MockSurveyCompletedInteractor interactor;
late MockBuildContext buildContext;
final outro = SurveyQuestionInfo();

beforeEach(() {
buildContext = MockBuildContext();

view = MockSurveyCompletedView();
when(view.context).thenReturn(buildContext);

router = MockSurveyCompletedRouter();

interactor = MockSurveyCompletedInteractor();
when(interactor.outro).thenReturn(outro);

presenter = SurveyCompletedPresenterImpl();
presenter.configure(view: view, interactor: interactor, router: router);
});

describe("it's stateDidInit emits", () {
beforeEach(() {
presenter.stateDidInit.add(null);
});

it("triggers view to set outro", () {
verify(view.setOutro(outro)).called(1);
});

describe("it's animationDidLoad emits", () {
beforeEach(() {
presenter.animationDidLoad.add(null);
});

it("triggers view to begin animation", () {
verify(view.beginAnimation()).called(1);
});
});
});

describe("it's animationDidFinish emits", () {
beforeEach(() async {
presenter.animationDidFinish.add(null);
await untilCalled(router.popBack(buildContext));
});

it("triggers view to set outro", () {
verify(router.popBack(buildContext)).called(1);
});
});
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Mocks generated by Mockito 5.0.7 from annotations
// in survey/test/modules/survey_completed/survey_completed_presenter_test.dart.
// Do not manually edit this file.

import 'package:flutter/src/widgets/framework.dart' as _i2;
import 'package:mockito/mockito.dart' as _i1;
import 'package:survey/models/survey_question_info.dart' as _i3;
import 'package:survey/modules/survey_completed/survey_completed_module.dart'
as _i4;

// ignore_for_file: comment_references
// ignore_for_file: unnecessary_parenthesis

// ignore_for_file: prefer_const_constructors

// ignore_for_file: avoid_redundant_argument_values

class _FakeBuildContext extends _i1.Fake implements _i2.BuildContext {}

class _FakeSurveyQuestionInfo extends _i1.Fake
implements _i3.SurveyQuestionInfo {}

/// A class which mocks [SurveyCompletedView].
///
/// See the documentation for Mockito's code generation for more information.
class MockSurveyCompletedView extends _i1.Mock
implements _i4.SurveyCompletedView {
MockSurveyCompletedView() {
_i1.throwOnMissingStub(this);
}

@override
set delegate(_i4.SurveyCompletedViewDelegate? _delegate) =>
super.noSuchMethod(Invocation.setter(#delegate, _delegate),
returnValueForMissingStub: null);
@override
_i2.BuildContext get context =>
(super.noSuchMethod(Invocation.getter(#context),
returnValue: _FakeBuildContext()) as _i2.BuildContext);
@override
void setOutro(_i3.SurveyQuestionInfo? outro) =>
super.noSuchMethod(Invocation.method(#setOutro, [outro]),
returnValueForMissingStub: null);
@override
void beginAnimation() =>
super.noSuchMethod(Invocation.method(#beginAnimation, []),
returnValueForMissingStub: null);
}

/// A class which mocks [SurveyCompletedRouter].
///
/// See the documentation for Mockito's code generation for more information.
class MockSurveyCompletedRouter extends _i1.Mock
implements _i4.SurveyCompletedRouter {
MockSurveyCompletedRouter() {
_i1.throwOnMissingStub(this);
}

@override
void popBack(_i2.BuildContext? context) =>
super.noSuchMethod(Invocation.method(#popBack, [context]),
returnValueForMissingStub: null);
}

/// A class which mocks [SurveyCompletedInteractor].
///
/// See the documentation for Mockito's code generation for more information.
class MockSurveyCompletedInteractor extends _i1.Mock
implements _i4.SurveyCompletedInteractor {
MockSurveyCompletedInteractor() {
_i1.throwOnMissingStub(this);
}

@override
_i3.SurveyQuestionInfo get outro =>
(super.noSuchMethod(Invocation.getter(#outro),
returnValue: _FakeSurveyQuestionInfo()) as _i3.SurveyQuestionInfo);
@override
set arguments(_i4.SurveyCompletedArguments? _arguments) =>
super.noSuchMethod(Invocation.setter(#arguments, _arguments),
returnValueForMissingStub: null);
@override
set delegate(_i4.SurveyCompletedInteractorDelegate? _delegate) =>
super.noSuchMethod(Invocation.setter(#delegate, _delegate),
returnValueForMissingStub: null);
}
36 changes: 36 additions & 0 deletions test/modules/survey_completed/survey_completed_router_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:quick_test/quick_test.dart';
import 'package:survey/modules/survey_completed/survey_completed_module.dart';

import '../../mocks/build_context.dart';
import '../../mocks/navigator_state.dart';

void main() {
describe("a SurveyCompleted router", () {
late SurveyCompletedRouter router;
late MockBuildContext buildContext;
late MockNavigatorState navigatorState;

beforeEach(() {
buildContext = MockBuildContext();
navigatorState = MockNavigatorState();

router = SurveyCompletedRouterImpl();
});

describe("it's popBack() is called", () {
beforeEach(() {
when(buildContext.findAncestorStateOfType<NavigatorState>())
.thenReturn(navigatorState);
when(navigatorState.pop()).thenAnswer((_) => Future.value());
router.popBack(buildContext);
});

it("triggers navigator to pop back", () {
verify(navigatorState.pop()).called(1);
});
});
});
}
77 changes: 77 additions & 0 deletions test/modules/survey_completed/survey_completed_view_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:lottie/lottie.dart';
import 'package:mockito/annotations.dart';
import 'package:quick_test/quick_widget_test.dart';
import 'package:survey/models/survey_question_info.dart';
import 'package:survey/models/user_info.dart';
import 'package:survey/core/viper/module.dart';
import 'package:mockito/mockito.dart';
import 'package:survey/modules/survey_completed/survey_completed_module.dart';
import '../../fakers/fake_module.dart';
import '../../helpers/behavior_subject_generator.dart';
import '../../helpers/extensions/widget_tester.dart';
import 'survey_completed_view_test.mocks.dart';

@GenerateMocks([SurveyCompletedViewDelegate])
void main() {
describe("a SurveyCompleted view", () {
late FakeModule<SurveyCompletedView, SurveyCompletedViewDelegate> module;
late MockSurveyCompletedViewDelegate delegate;
late BehaviorSubjectGenerator generator;
final outro = SurveyQuestionInfo();
outro.content = "thank you";

beforeEach((tester) async {
generator = BehaviorSubjectGenerator();
delegate = MockSurveyCompletedViewDelegate();
when(delegate.animationDidLoad)
.thenAnswer((realInvocation) => generator.make(0));
when(delegate.animationDidFinish)
.thenAnswer((realInvocation) => generator.make(1));
when(delegate.stateDidInit)
.thenAnswer((realInvocation) => generator.make(2));

module = FakeModule(
builder: () => const SurveyCompletedViewImpl(),
delegate: delegate,
);
ViewState.overriddenModule = module;
await tester.pumpModule(module);
await tester.pumpAndSettle();
});

describe("it's setOutro() is called", () {
beforeEach((tester) async {
module.view.setOutro(outro);
await tester.pumpAndSettle();
});

it("displays correct outro text", (tester) async {
expect(find.text(outro.content!), findsOneWidget);
});
});

describe("it's beginAnimation() is called", () {
beforeEach((tester) async {
await delegate.animationDidLoad.first;
module.view.beginAnimation();
await tester.pumpAndSettle();
});

it("trigger lottie begin animation", (tester) async {
final widget = tester
.widget<LottieBuilder>(find.byKey(SurveyCompletedView.lottieKey));
expect(widget.controller!.status, AnimationStatus.completed);
});

it("trigger delegate's emits", (tester) async {
expect(delegate.animationDidFinish, emits(null));
});
});
});
}
Loading

0 comments on commit 5203f4c

Please sign in to comment.