From 2c2a76d54dd4489ad7916ad47db61daecc9d4225 Mon Sep 17 00:00:00 2001 From: Gabriel Costa de Oliveira Date: Thu, 26 Dec 2024 23:25:58 -0300 Subject: [PATCH] test(#59): adiciona teste da view --- .../view/register_account_view.dart | 25 +- .../viewModel/register_view_model.dart | 4 +- .../view/register_account_view_test.dart | 134 +++++++ .../register_account_view_test.mocks.dart | 336 ++++++++++++++++++ 4 files changed, 483 insertions(+), 16 deletions(-) create mode 100644 test/ui/register_account/view/register_account_view_test.dart create mode 100644 test/ui/register_account/view/register_account_view_test.mocks.dart diff --git a/lib/ui/register_account/view/register_account_view.dart b/lib/ui/register_account/view/register_account_view.dart index 6beae7c..ed81652 100644 --- a/lib/ui/register_account/view/register_account_view.dart +++ b/lib/ui/register_account/view/register_account_view.dart @@ -21,7 +21,7 @@ class RegisterAccount extends StatelessWidget { Widget build(BuildContext context) { return ChangeNotifierProvider( create: (context) => RegisterAccountViewModel(), - child: const RegisterAccountScreen(), + child: const RegisterAccountScreen(), ); } } @@ -64,10 +64,12 @@ class RegisterAccountScreen extends StatelessWidget { key: viewModel.formKey, child: Column(children: [ TextName( + key: const Key('nameField'), label: 'Nome', controller: viewModel.nameController, padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 20)), TextName( + key: const Key('userNameField'), label: 'Nome de Usuário', controller: viewModel.userNameController, padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 20)), @@ -111,27 +113,24 @@ class RegisterAccountScreen extends StatelessWidget { final viewModel = Provider.of(context); return ListenableBuilder( - - listenable: viewModel.registercomand, + listenable: viewModel.registerCommand, builder: (context, child) { - if (viewModel.registercomand.isError) { + if (viewModel.registerCommand.isError) { WidgetsBinding.instance.addPostFrameCallback((_) { showDialog( context: context, builder: (BuildContext context) => ErrorPopUp( - content: Text( - viewModel.registercomand.result!.asError!.error.toString()), + content: Text(viewModel.registerCommand.result!.asError!.error + .toString()), ), ); }); } - if (viewModel.registercomand.isOk) { + if (viewModel.registerCommand.isOk) { WidgetsBinding.instance.addPostFrameCallback((_) { ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text( - 'conta criada com sucesso!!!')), + const SnackBar(content: Text('conta criada com sucesso!!!')), ); }); } @@ -141,9 +140,9 @@ class RegisterAccountScreen extends StatelessWidget { height: 64, child: ElevatedButton( onPressed: () async { - viewModel.registercomand.execute(); + viewModel.registerCommand.execute(); }, - child: viewModel.registercomand.running + child: viewModel.registerCommand.running ? const CircularProgressIndicator(value: null) : const Text('Registrar'), ), @@ -171,6 +170,4 @@ class RegisterAccountScreen extends StatelessWidget { ), ); } - } - diff --git a/lib/ui/register_account/viewModel/register_view_model.dart b/lib/ui/register_account/viewModel/register_view_model.dart index a7700cc..164d91b 100644 --- a/lib/ui/register_account/viewModel/register_view_model.dart +++ b/lib/ui/register_account/viewModel/register_view_model.dart @@ -13,10 +13,10 @@ class RegisterAccountViewModel extends ChangeNotifier { bool isTermsAccepted = false; - late Command0 registercomand; + late Command0 registerCommand; RegisterAccountViewModel() { - registercomand = Command0(_register); + registerCommand = Command0(_register); } Future> _register() async { diff --git a/test/ui/register_account/view/register_account_view_test.dart b/test/ui/register_account/view/register_account_view_test.dart new file mode 100644 index 0000000..29f83ab --- /dev/null +++ b/test/ui/register_account/view/register_account_view_test.dart @@ -0,0 +1,134 @@ +import 'package:aranduapp/core/state/command.dart'; +import 'package:aranduapp/ui/register_account/view/register_account_view.dart'; +import 'package:aranduapp/ui/shared/ErrorPopUp.dart'; +import 'package:aranduapp/ui/shared/TextAndLink.dart'; +import 'package:aranduapp/ui/shared/TextEmail.dart'; +import 'package:aranduapp/ui/shared/TextName.dart'; +import 'package:aranduapp/ui/shared/TextPassword.dart'; +import 'package:aranduapp/ui/shared/TitleSlogan.dart'; +import 'package:async/async.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; +import 'package:provider/provider.dart'; + +@GenerateNiceMocks([MockSpec(), MockSpec()]) +import 'package:aranduapp/ui/register_account/viewModel/register_view_model.dart'; + +import 'register_account_view_test.mocks.dart'; + +void main() { + late MockRegisterAccountViewModel mockViewModel; + late MockCommand0 mockCommand0; + + setUp(() { + mockViewModel = MockRegisterAccountViewModel(); + mockCommand0 = MockCommand0(); + + when(mockCommand0.execute()).thenAnswer((_) async => Result.value(null)); + + when(mockViewModel.registerCommand).thenReturn(mockCommand0); + when(mockViewModel.formKey).thenReturn(GlobalKey()); + when(mockViewModel.nameController).thenReturn(TextEditingController()); + when(mockViewModel.emailController).thenReturn(TextEditingController()); + when(mockViewModel.userNameController).thenReturn(TextEditingController()); + when(mockViewModel.passwordController).thenReturn(TextEditingController()); + when(mockViewModel.isTermsAccepted).thenReturn(false); + }); + + Widget createLoginScreen(MockRegisterAccountViewModel mockViewModel) { + return ChangeNotifierProvider.value( + value: mockViewModel, + builder: (context, child) { + return const MaterialApp( + home: RegisterAccountScreen(), + ); + }, + ); + } + + testWidgets('Register Account screen displays fields and send button', + (WidgetTester tester) async { + when(mockViewModel.registerCommand).thenReturn( + Command0(() => Future.delayed(const Duration(seconds: 1)))); + + await tester.pumpWidget(createLoginScreen(mockViewModel)); + await tester.pump(); + + expect(find.byType(TitleSlogan), findsOneWidget); + expect(find.byKey(const Key('nameField')), findsOneWidget); + expect(find.byKey(const Key('userNameField')), findsOneWidget); + expect(find.byType(TextEmail), findsOneWidget); + expect(find.byType(TextPassWord), findsOneWidget); + expect(find.byType(Checkbox), findsOneWidget); + + expect(find.text('Registrar'), findsOneWidget); + expect(find.byType(TextAndLink), findsOneWidget); + }); + + testWidgets('Test sending the request', (WidgetTester tester) async { + await tester.pumpWidget(createLoginScreen(mockViewModel)); + + when(mockViewModel.registerCommand).thenReturn(mockCommand0); + + final sendButton = find.text('Registrar'); + + await tester.tap(sendButton); + await tester.pump(); + + verify(mockCommand0.execute()).called(1); + }); + + testWidgets('Register Account Test User Input', (WidgetTester tester) async { + when(mockViewModel.registerCommand).thenReturn(mockCommand0); + + await tester.pumpWidget(createLoginScreen(mockViewModel)); + + const name = 'test'; + const email = 'test@example.com'; + const userName = 'test123'; + const password = 'password123'; + + await tester.pumpAndSettle(); + + await tester.enterText(find.byKey(const Key('nameField')), name); + await tester.enterText(find.byKey(const Key('userNameField')), userName); + await tester.enterText(find.byType(TextEmail), email); + await tester.enterText(find.byType(TextPassWord), password); + await tester.pumpAndSettle(); + + expect(mockViewModel.nameController.text, name); + expect(mockViewModel.userNameController.text, userName); + expect(mockViewModel.passwordController.text, password); + expect(mockViewModel.emailController.text, email); + }); + + testWidgets('Register Account user notification snackbar', + (WidgetTester tester) async { + when(mockViewModel.registerCommand).thenReturn(mockCommand0); + when(mockCommand0.isOk).thenReturn(true); + + await tester.pumpWidget(createLoginScreen(mockViewModel)); + await tester.pumpAndSettle(); + + expect(find.byType(SnackBar), findsOneWidget); + }); + + testWidgets('Register Account user notification popup error', + (WidgetTester tester) async { + when(mockViewModel.registerCommand).thenReturn(mockCommand0); + when(mockCommand0.isError).thenReturn(true); + + const error = 'error message.'; + + when(mockCommand0.result).thenReturn(Result.error(error)); + + await tester.pumpWidget(createLoginScreen(mockViewModel)); + await tester.pumpAndSettle(); + + expect(find.byType(ErrorPopUp), findsOneWidget); + expect(find.text(error), findsOneWidget); + }); + +} diff --git a/test/ui/register_account/view/register_account_view_test.mocks.dart b/test/ui/register_account/view/register_account_view_test.mocks.dart new file mode 100644 index 0000000..a2b45f3 --- /dev/null +++ b/test/ui/register_account/view/register_account_view_test.mocks.dart @@ -0,0 +1,336 @@ +// Mocks generated by Mockito 5.4.4 from annotations +// in aranduapp/test/ui/register_account/view/register_account_view_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i6; + +import 'package:aranduapp/core/state/command.dart' as _i3; +import 'package:aranduapp/ui/register_account/viewModel/register_view_model.dart' + as _i5; +import 'package:async/async.dart' as _i4; +import 'package:flutter/material.dart' as _i1; +import 'package:mockito/mockito.dart' as _i2; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakeGlobalKey_0> + extends _i2.SmartFake implements _i1.GlobalKey { + _FakeGlobalKey_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeTextEditingController_1 extends _i2.SmartFake + implements _i1.TextEditingController { + _FakeTextEditingController_1( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeCommand0_2 extends _i2.SmartFake implements _i3.Command0 { + _FakeCommand0_2( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeResult_3 extends _i2.SmartFake implements _i4.Result { + _FakeResult_3( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [RegisterAccountViewModel]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockRegisterAccountViewModel extends _i2.Mock + implements _i5.RegisterAccountViewModel { + @override + _i1.GlobalKey<_i1.FormState> get formKey => (super.noSuchMethod( + Invocation.getter(#formKey), + returnValue: _FakeGlobalKey_0<_i1.FormState>( + this, + Invocation.getter(#formKey), + ), + returnValueForMissingStub: _FakeGlobalKey_0<_i1.FormState>( + this, + Invocation.getter(#formKey), + ), + ) as _i1.GlobalKey<_i1.FormState>); + + @override + _i1.TextEditingController get nameController => (super.noSuchMethod( + Invocation.getter(#nameController), + returnValue: _FakeTextEditingController_1( + this, + Invocation.getter(#nameController), + ), + returnValueForMissingStub: _FakeTextEditingController_1( + this, + Invocation.getter(#nameController), + ), + ) as _i1.TextEditingController); + + @override + _i1.TextEditingController get emailController => (super.noSuchMethod( + Invocation.getter(#emailController), + returnValue: _FakeTextEditingController_1( + this, + Invocation.getter(#emailController), + ), + returnValueForMissingStub: _FakeTextEditingController_1( + this, + Invocation.getter(#emailController), + ), + ) as _i1.TextEditingController); + + @override + _i1.TextEditingController get userNameController => (super.noSuchMethod( + Invocation.getter(#userNameController), + returnValue: _FakeTextEditingController_1( + this, + Invocation.getter(#userNameController), + ), + returnValueForMissingStub: _FakeTextEditingController_1( + this, + Invocation.getter(#userNameController), + ), + ) as _i1.TextEditingController); + + @override + _i1.TextEditingController get passwordController => (super.noSuchMethod( + Invocation.getter(#passwordController), + returnValue: _FakeTextEditingController_1( + this, + Invocation.getter(#passwordController), + ), + returnValueForMissingStub: _FakeTextEditingController_1( + this, + Invocation.getter(#passwordController), + ), + ) as _i1.TextEditingController); + + @override + bool get isTermsAccepted => (super.noSuchMethod( + Invocation.getter(#isTermsAccepted), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); + + @override + set isTermsAccepted(bool? _isTermsAccepted) => super.noSuchMethod( + Invocation.setter( + #isTermsAccepted, + _isTermsAccepted, + ), + returnValueForMissingStub: null, + ); + + @override + _i3.Command0 get registerCommand => (super.noSuchMethod( + Invocation.getter(#registerCommand), + returnValue: _FakeCommand0_2( + this, + Invocation.getter(#registerCommand), + ), + returnValueForMissingStub: _FakeCommand0_2( + this, + Invocation.getter(#registerCommand), + ), + ) as _i3.Command0); + + @override + set registerCommand(_i3.Command0? _registerCommand) => + super.noSuchMethod( + Invocation.setter( + #registerCommand, + _registerCommand, + ), + returnValueForMissingStub: null, + ); + + @override + bool get hasListeners => (super.noSuchMethod( + Invocation.getter(#hasListeners), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); + + @override + void toggleTermsAccepted(bool? value) => super.noSuchMethod( + Invocation.method( + #toggleTermsAccepted, + [value], + ), + returnValueForMissingStub: null, + ); + + @override + void addListener(dynamic listener) => super.noSuchMethod( + Invocation.method( + #addListener, + [listener], + ), + returnValueForMissingStub: null, + ); + + @override + void removeListener(dynamic listener) => super.noSuchMethod( + Invocation.method( + #removeListener, + [listener], + ), + returnValueForMissingStub: null, + ); + + @override + void dispose() => super.noSuchMethod( + Invocation.method( + #dispose, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void notifyListeners() => super.noSuchMethod( + Invocation.method( + #notifyListeners, + [], + ), + returnValueForMissingStub: null, + ); +} + +/// A class which mocks [Command0]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockCommand0 extends _i2.Mock implements _i3.Command0 { + @override + _i6.Future<_i4.Result> Function() get action => (super.noSuchMethod( + Invocation.getter(#action), + returnValue: () => _i6.Future<_i4.Result>.value(_FakeResult_3( + this, + Invocation.getter(#action), + )), + returnValueForMissingStub: () => + _i6.Future<_i4.Result>.value(_FakeResult_3( + this, + Invocation.getter(#action), + )), + ) as _i6.Future<_i4.Result> Function()); + + @override + bool get isError => (super.noSuchMethod( + Invocation.getter(#isError), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); + + @override + bool get isOk => (super.noSuchMethod( + Invocation.getter(#isOk), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); + + @override + bool get running => (super.noSuchMethod( + Invocation.getter(#running), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); + + @override + bool get hasListeners => (super.noSuchMethod( + Invocation.getter(#hasListeners), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); + + @override + _i6.Future<_i4.Result> execute() => (super.noSuchMethod( + Invocation.method( + #execute, + [], + ), + returnValue: _i6.Future<_i4.Result>.value(_FakeResult_3( + this, + Invocation.method( + #execute, + [], + ), + )), + returnValueForMissingStub: + _i6.Future<_i4.Result>.value(_FakeResult_3( + this, + Invocation.method( + #execute, + [], + ), + )), + ) as _i6.Future<_i4.Result>); + + @override + void addListener(dynamic listener) => super.noSuchMethod( + Invocation.method( + #addListener, + [listener], + ), + returnValueForMissingStub: null, + ); + + @override + void removeListener(dynamic listener) => super.noSuchMethod( + Invocation.method( + #removeListener, + [listener], + ), + returnValueForMissingStub: null, + ); + + @override + void dispose() => super.noSuchMethod( + Invocation.method( + #dispose, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void notifyListeners() => super.noSuchMethod( + Invocation.method( + #notifyListeners, + [], + ), + returnValueForMissingStub: null, + ); +}