Skip to content

Commit

Permalink
chore: write tests for home screen (#26)
Browse files Browse the repository at this point in the history
  • Loading branch information
markgravity committed May 13, 2021
1 parent 838beb6 commit a67091a
Show file tree
Hide file tree
Showing 8 changed files with 824 additions and 0 deletions.
98 changes: 98 additions & 0 deletions test/modules/home/home_interactor_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
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_info.dart';
import 'package:survey/models/user_info.dart';
import 'package:survey/modules/home/home_module.dart';
import 'package:survey/repositories/auth_repository.dart';
import 'package:survey/repositories/survey_repository.dart';
import 'package:survey/services/locator/locator_service.dart';
import '../../helpers/behavior_subject_generator.dart';
import 'home_interactor_test.mocks.dart';

@GenerateMocks([HomeInteractorDelegate, SurveyRepository, AuthRepository])
void main() {
describe("a Home interactor", () {
late HomeInteractor interactor;
late MockHomeInteractorDelegate delegate;
late MockSurveyRepository surveyRepository;
late MockAuthRepository authRepository;
late BehaviorSubjectGenerator generator;

beforeEach(() {
generator = BehaviorSubjectGenerator();

delegate = MockHomeInteractorDelegate();
when(delegate.isSurveysCachedDidGet)
.thenAnswer((realInvocation) => generator.make(0));
when(delegate.authenticatedUserDidGet)
.thenAnswer((realInvocation) => generator.make(1));
when(delegate.surveysDidFetch)
.thenAnswer((realInvocation) => generator.make(2));
when(delegate.surveysDidFailToFetch)
.thenAnswer((realInvocation) => generator.make(3));

surveyRepository = MockSurveyRepository();
locator.registerSingleton<SurveyRepository>(surveyRepository);

authRepository = MockAuthRepository();
locator.registerSingleton<AuthRepository>(authRepository);

interactor = HomeInteractorImpl();
interactor.delegate = delegate;
});

describe("it's getIsSurveysCached is called", () {
beforeEach(() {
when(surveyRepository.isSurveysCached)
.thenAnswer((realInvocation) => Future.value(true));
interactor.getIsSurveysCached();
});

it("triggers delegate's isSurveysCachedDidGet emits", () {
expect(delegate.isSurveysCachedDidGet, emits(true));
});
});

describe("it's getAuthenticatedUser is called", () {
final user = UserInfo();
beforeEach(() {
when(authRepository.user).thenReturn(user);
interactor.getAuthenticatedUser();
});

it("triggers delegate's authenticatedUserDidGet emits", () {
expect(delegate.authenticatedUserDidGet, emits(user));
});
});

describe("it's fetchSurveys is called", () {
context("when surveyRepository's fetchSurveys return success", () {
final surveys = List<SurveyInfo>.empty();
beforeEach(() {
when(surveyRepository.fetchSurveys(force: anyNamed("force")))
.thenAnswer((realInvocation) => Future.value(surveys));
interactor.fetchSurveys();
});

it("triggers delegate's surveysDidFetch emits", () {
expect(delegate.surveysDidFetch, emits(surveys));
});
});

context("when surveyRepository's fetchSurveys return failure", () {
final exception = Exception();
beforeEach(() {
when(surveyRepository.fetchSurveys(force: anyNamed("force")))
.thenAnswer((realInvocation) => Future.error(exception));
interactor.fetchSurveys();
});

it("triggers delegate's surveysDidFailToFetch emits", () {
expect(delegate.surveysDidFailToFetch, emits(exception));
});
});
});
});
}
113 changes: 113 additions & 0 deletions test/modules/home/home_interactor_test.mocks.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// Mocks generated by Mockito 5.0.7 from annotations
// in survey/test/modules/home/home_interactor_test.dart.
// Do not manually edit this file.

import 'dart:async' as _i7;

import 'package:mockito/mockito.dart' as _i1;
import 'package:rxdart/src/subjects/behavior_subject.dart' as _i2;
import 'package:survey/models/survey_info.dart' as _i4;
import 'package:survey/models/user_info.dart' as _i5;
import 'package:survey/modules/home/home_module.dart' as _i3;
import 'package:survey/repositories/auth_repository.dart' as _i8;
import 'package:survey/repositories/survey_repository.dart' as _i6;

// ignore_for_file: comment_references
// ignore_for_file: unnecessary_parenthesis

// ignore_for_file: prefer_const_constructors

// ignore_for_file: avoid_redundant_argument_values

class _FakeBehaviorSubject<T> extends _i1.Fake
implements _i2.BehaviorSubject<T> {}

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

@override
_i2.BehaviorSubject<bool> get isSurveysCachedDidGet => (super.noSuchMethod(
Invocation.getter(#isSurveysCachedDidGet),
returnValue: _FakeBehaviorSubject<bool>()) as _i2.BehaviorSubject<bool>);
@override
_i2.BehaviorSubject<List<_i4.SurveyInfo>> get surveysDidFetch =>
(super.noSuchMethod(Invocation.getter(#surveysDidFetch),
returnValue: _FakeBehaviorSubject<List<_i4.SurveyInfo>>())
as _i2.BehaviorSubject<List<_i4.SurveyInfo>>);
@override
_i2.BehaviorSubject<Exception> get surveysDidFailToFetch =>
(super.noSuchMethod(Invocation.getter(#surveysDidFailToFetch),
returnValue: _FakeBehaviorSubject<Exception>())
as _i2.BehaviorSubject<Exception>);
@override
_i2.BehaviorSubject<_i5.UserInfo> get authenticatedUserDidGet =>
(super.noSuchMethod(Invocation.getter(#authenticatedUserDidGet),
returnValue: _FakeBehaviorSubject<_i5.UserInfo>())
as _i2.BehaviorSubject<_i5.UserInfo>);
}

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

@override
_i7.Future<bool> get isSurveysCached =>
(super.noSuchMethod(Invocation.getter(#isSurveysCached),
returnValue: Future<bool>.value(false)) as _i7.Future<bool>);
@override
_i7.Future<List<_i4.SurveyInfo>> fetchSurveys({bool? force}) =>
(super.noSuchMethod(Invocation.method(#fetchSurveys, [], {#force: force}),
returnValue:
Future<List<_i4.SurveyInfo>>.value(<_i4.SurveyInfo>[]))
as _i7.Future<List<_i4.SurveyInfo>>);
}

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

@override
bool get isAuthenticated => (super
.noSuchMethod(Invocation.getter(#isAuthenticated), returnValue: false)
as bool);
@override
_i7.Future<void> login({String? email, String? password}) =>
(super.noSuchMethod(
Invocation.method(#login, [], {#email: email, #password: password}),
returnValue: Future<void>.value(null),
returnValueForMissingStub: Future.value()) as _i7.Future<void>);
@override
_i7.Future<void> logout() =>
(super.noSuchMethod(Invocation.method(#logout, []),
returnValue: Future<void>.value(null),
returnValueForMissingStub: Future.value()) as _i7.Future<void>);
@override
_i7.Future<void> attempt() =>
(super.noSuchMethod(Invocation.method(#attempt, []),
returnValue: Future<void>.value(null),
returnValueForMissingStub: Future.value()) as _i7.Future<void>);
@override
_i7.Future<void> fetchUser() =>
(super.noSuchMethod(Invocation.method(#fetchUser, []),
returnValue: Future<void>.value(null),
returnValueForMissingStub: Future.value()) as _i7.Future<void>);
@override
_i7.Future<void> attemptAndFetchUser() =>
(super.noSuchMethod(Invocation.method(#attemptAndFetchUser, []),
returnValue: Future<void>.value(null),
returnValueForMissingStub: Future.value()) as _i7.Future<void>);
}
27 changes: 27 additions & 0 deletions test/modules/home/home_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/home/home_module.dart';

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

void main() {
describe("a Home module", () {
late HomeModule module;
beforeEach(() {
module = HomeModule();
});

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

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

it("returns LandingViewImpl", () {
expect(widget, isA<HomeViewImpl>());
});
});
});
}
140 changes: 140 additions & 0 deletions test/modules/home/home_presenter_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:quick_test/quick_test.dart';
import 'package:survey/models/survey_info.dart';
import 'package:survey/models/user_info.dart';
import 'package:survey/modules/home/home_module.dart';

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

@GenerateMocks([HomeView, HomeRouter, HomeInteractor])
void main() {
describe("a Home presenter", () {
late HomePresenterImpl presenter;
late MockHomeView view;
late MockHomeRouter router;
late MockHomeInteractor interactor;
late MockBuildContext buildContext;

beforeEach(() {
buildContext = MockBuildContext();

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

router = MockHomeRouter();

interactor = MockHomeInteractor();

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

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

it("triggers interactor to get isSurveysCached and authenticatedUser",
() {
verify(interactor.getIsSurveysCached()).called(1);
verify(interactor.getAuthenticatedUser()).called(1);
});
});

describe("it's showDetailButtonDidTap emits", () {
final survey = SurveyInfo();

beforeEach(() {
presenter.showDetailButtonDidTap.add(survey);
});

it("triggers router to push to Survey Detail screen", () {
verify(router.pushToSurveyDetail(context: buildContext, survey: survey))
.called(1);
});
});

describe("it's surveysDidFetch emits", () {
final surveys = List<SurveyInfo>.empty();

beforeEach(() {
presenter.surveysDidFetch.add(surveys);
});

it("trigger view to stop skeleton animation, dismiss progress hud and show surveys",
() {
verify(view.stopSkeletonAnimation()).called(1);
verify(view.showSurveys(surveys)).called(1);
verify(view.dismissProgressHUD()).called(1);
});
});

describe("it's surveysDidFailToFetch emits", () {
final exception = Exception();

beforeEach(() {
presenter.surveysDidFailToFetch.add(exception);
});

it("trigger view to stop skeleton animation, dismiss progress hud and alert error",
() {
verify(view.stopSkeletonAnimation()).called(1);
verify(view.alert(exception)).called(1);
verify(view.dismissProgressHUD()).called(1);
});
});

describe("it's isSurveysCachedDidGet emits", () {
context("when isSurveysCached is true", () {
beforeEach(() {
presenter.isSurveysCachedDidGet.add(true);
});

it("trigger interactor to fetch surveys", () {
verify(interactor.fetchSurveys()).called(1);
});
});

context("when isSurveysCached is false", () {
beforeEach(() {
presenter.isSurveysCachedDidGet.add(false);
});

it("trigger interactor to fetch surveys", () {
verify(interactor.fetchSurveys()).called(1);
});

it("trigger view to begin skeleton animation", () {
verify(view.beginSkeletonAnimation()).called(1);
});
});
});

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

it("trigger view to show progress hud", () {
verify(view.showProgressHUD()).called(1);
});

it("trigger interactor to force fetch surveys", () {
verify(interactor.fetchSurveys(force: true)).called(1);
});
});

describe("it's authenticatedUserDidGet emits", () {
final user = UserInfo();
beforeEach(() {
presenter.authenticatedUserDidGet.add(user);
});

it("trigger view to show user", () {
verify(view.showUser(user)).called(1);
});
});
});
}
Loading

0 comments on commit a67091a

Please sign in to comment.