From f149134ab006de18142554a23aefc7e719b96ede Mon Sep 17 00:00:00 2001 From: Gabriel Moro Date: Sat, 20 Sep 2025 12:08:00 -0300 Subject: [PATCH 1/5] Ignore generated code --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 899de41..0122a41 100644 --- a/.gitignore +++ b/.gitignore @@ -168,4 +168,5 @@ app.*.symbols *.freezed.dart *.g.dart */di.config.dart -*.mocks.dart \ No newline at end of file +*.mocks.dart +lib/core/di/di.config.dart From a4d8b2780eb0d1625ba7ba9890e919fa25b4bf89 Mon Sep 17 00:00:00 2001 From: Gabriel Moro Date: Sat, 20 Sep 2025 12:14:02 -0300 Subject: [PATCH 2/5] Organize test according to our directory structure --- test/{ => layers/data/datasource}/search_data_source_test.dart | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{ => layers/data/datasource}/search_data_source_test.dart (100%) diff --git a/test/search_data_source_test.dart b/test/layers/data/datasource/search_data_source_test.dart similarity index 100% rename from test/search_data_source_test.dart rename to test/layers/data/datasource/search_data_source_test.dart From bb8746d4b55f5d7a445b7be1600b4dfed3f800ba Mon Sep 17 00:00:00 2001 From: Gabriel Moro Date: Sat, 20 Sep 2025 12:52:51 -0300 Subject: [PATCH 3/5] Unit tests for get_book_details --- .../layers/domain/fakes/fake_book_domain.dart | 10 ++++ test/layers/domain/get_book_details_test.dart | 52 +++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 test/layers/domain/fakes/fake_book_domain.dart create mode 100644 test/layers/domain/get_book_details_test.dart diff --git a/test/layers/domain/fakes/fake_book_domain.dart b/test/layers/domain/fakes/fake_book_domain.dart new file mode 100644 index 0000000..e7aa8a9 --- /dev/null +++ b/test/layers/domain/fakes/fake_book_domain.dart @@ -0,0 +1,10 @@ +import 'package:mibook/layers/domain/models/book_list_domain.dart'; + +final fakeBookDomain = BookDomain( + id: 'id', + title: 'title', + description: 'description', + thumbnail: 'thumbnail', + authors: [], + kind: 'kind', +); diff --git a/test/layers/domain/get_book_details_test.dart b/test/layers/domain/get_book_details_test.dart new file mode 100644 index 0000000..c169e43 --- /dev/null +++ b/test/layers/domain/get_book_details_test.dart @@ -0,0 +1,52 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:mibook/layers/domain/repository/search_repository.dart'; +import 'package:mibook/layers/domain/usecases/get_book_details.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; +import 'fakes/fake_book_domain.dart'; + +@GenerateNiceMocks([MockSpec()]) +import 'get_book_details_test.mocks.dart'; + +void main() { + late MockISearchRepository mockSearchRepository; + late GetBookDetails getBookDetails; + + setUp(() { + mockSearchRepository = MockISearchRepository(); + getBookDetails = GetBookDetails( + mockSearchRepository, + ); + }); + + group('GetBookDetails', () { + test('searchById returns BookDetails on success', () async { + when( + mockSearchRepository.searchById( + id: 'id', + ), + ).thenAnswer((_) async => Future.value(fakeBookDomain)); + + final result = await getBookDetails.call(id: 'id'); + expect(result, fakeBookDomain); + }); + + test('searchById returns BookDetails on failure', () async { + when( + mockSearchRepository.searchById( + id: 'id', + ), + ).thenThrow(Exception('Something went wrong')); + + var error = false; + try { + await getBookDetails.call(id: 'id'); + error = false; + } catch (e) { + error = true; + } + + expect(error, isTrue); + }); + }); +} From e35d9592a55a9c42c8c0b5b8d70b1bc047861d6f Mon Sep 17 00:00:00 2001 From: Gabriel Moro Date: Sat, 20 Sep 2025 12:58:44 -0300 Subject: [PATCH 4/5] Update test names to match to the current use case --- test/layers/domain/get_book_details_test.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/layers/domain/get_book_details_test.dart b/test/layers/domain/get_book_details_test.dart index c169e43..ee5165e 100644 --- a/test/layers/domain/get_book_details_test.dart +++ b/test/layers/domain/get_book_details_test.dart @@ -20,7 +20,7 @@ void main() { }); group('GetBookDetails', () { - test('searchById returns BookDetails on success', () async { + test('call returns BookDetails on success', () async { when( mockSearchRepository.searchById( id: 'id', @@ -31,7 +31,7 @@ void main() { expect(result, fakeBookDomain); }); - test('searchById returns BookDetails on failure', () async { + test('call returns BookDetails on failure', () async { when( mockSearchRepository.searchById( id: 'id', From 6e909187743ded9e9d116baf3843447d2590978a Mon Sep 17 00:00:00 2001 From: Gabriel Moro Date: Sat, 20 Sep 2025 20:01:40 -0300 Subject: [PATCH 5/5] Unit tests for search books --- .../domain/fakes/fake_book_list_domain.dart | 9 +++ test/layers/domain/search_books_test.dart | 61 +++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 test/layers/domain/fakes/fake_book_list_domain.dart create mode 100644 test/layers/domain/search_books_test.dart diff --git a/test/layers/domain/fakes/fake_book_list_domain.dart b/test/layers/domain/fakes/fake_book_list_domain.dart new file mode 100644 index 0000000..8c7a890 --- /dev/null +++ b/test/layers/domain/fakes/fake_book_list_domain.dart @@ -0,0 +1,9 @@ + +import 'package:mibook/layers/domain/models/book_list_domain.dart'; + +import 'fake_book_domain.dart'; + +final fakeBookListDomain = BookListDomain( + totalItems: 1, + books: [fakeBookDomain], +); diff --git a/test/layers/domain/search_books_test.dart b/test/layers/domain/search_books_test.dart new file mode 100644 index 0000000..ab033ac --- /dev/null +++ b/test/layers/domain/search_books_test.dart @@ -0,0 +1,61 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:mibook/layers/domain/repository/search_repository.dart'; +import 'package:mibook/layers/domain/usecases/search_books.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; + +import 'fakes/fake_book_list_domain.dart'; + +@GenerateNiceMocks([MockSpec()]) +import 'search_books_test.mocks.dart'; + +void main() { + late MockISearchRepository mockSearchRepository; + late SearchBooks searchBooks; + + setUp(() { + mockSearchRepository = MockISearchRepository(); + searchBooks = SearchBooks( + mockSearchRepository, + ); + }); + + group('SearchBooks', () { + test('call returns BookListDomain on success', () async { + when( + mockSearchRepository.searchByTitle( + initTitle: 'initTitle', + startIndex: 0, + ), + ).thenAnswer((_) async => Future.value(fakeBookListDomain)); + + final result = await searchBooks.call( + initTitle: 'initTitle', + startIndex: 0, + ); + expect(result, fakeBookListDomain); + }); + + test('call returns BookListDomain on failure', () async { + when( + mockSearchRepository.searchByTitle( + initTitle: 'initTitle', + startIndex: 0, + ), + ).thenThrow(Exception('Something went wrong')); + + var error = false; + try { + await searchBooks.call( + initTitle: 'initTitle', + startIndex: 0, + ); + error = false; + } catch (e) { + error = true; + } + + expect(error, isTrue); + }); + }); +}