From 28d92eff91f3e39c2d671fe8dbdb9b7b07763a3d Mon Sep 17 00:00:00 2001 From: fluttermiddlepodcast Date: Sat, 31 Jan 2026 15:27:36 +0300 Subject: [PATCH 1/3] updated tests and docs --- README.md | 55 +++++++++++------- test/features/users/users_bloc_test.dart | 73 ++++++++++-------------- 2 files changed, 65 insertions(+), 63 deletions(-) diff --git a/README.md b/README.md index 8952bd2..6400dc6 100644 --- a/README.md +++ b/README.md @@ -5,26 +5,41 @@ ## Описание -Небольшой проект для демонстрации возможностей BLoC. - -## Видео с разбором кода - -- [Flutter Developer Learn #1 - Дополнение к выпуску про базу BLoC](https://youtu.be/GO1AWSdlCEI) -- [Flutter Developer Learn #2 - BlocBuilder](https://youtu.be/98iF13KKdss) -- [Flutter Developer Learn #3 - Реализация состояний в BLoC](https://youtu.be/YBLzMV9dVmI) -- [Flutter Developer Learn #4 - BlocListener](https://youtu.be/3rMMqciUd4Y) -- [Flutter Developer Learn #5 - Cubit](https://youtu.be/CuaeQJBcBYA) -- [Flutter Developer Learn #6 - feature-first и layer-first подходы для организации Flutter-проектов](https://youtu.be/WTnIakTAU3I) -- [Flutter Developer Learn #7 - Генерация шаблонного кода / mason](https://youtu.be/yVxDoe88foU) -- [Flutter Developer Learn #8 - Как не нужно выстраивать коммуникацию между блоками](https://youtu.be/tLquqILV_j4) -- [Flutter Developer Learn #9 - Ручной copyWith и его проблемы](https://youtu.be/Kurlder2WdE) -- [Flutter Developer Learn #10 - BlocConsumer 2](https://youtu.be/WKjpXTSwQuU) -- [bloc_concurrency](https://youtu.be/tPSqLA7i-3U) -- [Оптимизация GitHub Actions](https://youtu.be/NxY6mGaIzKY) -- [Шиммеры / Скелетоны](https://youtu.be/L-Jgfsl1lmM) -- [make / Makefile для Flutter-проектов](https://youtu.be/CMj70A5k17E) -- [bloc + пагинация = ❤️](https://youtu.be/0L-LgbR3EgM) -- [bloc_tools: генерируем блоки из консоли](https://youtu.be/c-CXiQZVYBs) +Небольшой проект для демонстрации возможностей [bloc](https://pub.dev/packages/bloc) и [flutter_bloc](https://pub.dev/packages/flutter_bloc). + +## Материалы из репозитория + +### Основы + +— [Flutter Developer Talks #12 - BLoC](https://podcasts.apple.com/ru/podcast/flutter-developer-talks/id1648922484?i=1000644267848) +— [Flutter Developer Learn #1 - Дополнение к выпуску про базу BLoC](https://t.me/fluttermiddlepodcast/173) +— [Flutter Developer Learn #2 - BlocBuilder](https://youtu.be/98iF13KKdss) +— [Flutter Developer Learn #3 - Реализация состояний в BLoC](https://youtu.be/YBLzMV9dVmI) +— [Flutter Developer Learn #4 - BlocListener](https://t.me/fluttermiddlepodcast/277) +— [Flutter Developer Learn #5 - Cubit](https://t.me/fluttermiddlepodcast/279) +— [Flutter Developer Learn #8 - Как не нужно выстраивать коммуникацию между блоками](https://t.me/fluttermiddlepodcast/300) +— [Flutter Developer Learn #10 - BlocConsumer 2](https://t.me/fluttermiddlepodcast/338) + +### Продакшн + +— [Flutter Developer Learn #6 - feature-first и layer-first подходы для организации Flutter-проектов](https://t.me/fluttermiddlepodcast/281) +— [bloc_concurrency](https://t.me/fluttermiddlepodcast/379) +— [Шиммеры / Скелетоны](https://t.me/fluttermiddlepodcast/391) +— [bloc + пагинация = ❤️](https://t.me/fluttermiddlepodcast/421) +— [hydrated_bloc: сохраняем состояние блоков](https://t.me/fluttermiddlepodcast/426) +— [replay_bloc: откатываем состояния блоков и кубитов](https://t.me/fluttermiddlepodcast/427) + +### Тулинг + +— [Flutter Developer Learn #7 - Генерация шаблонного кода / mason](https://t.me/fluttermiddlepodcast/297) +— [bloc_tools: генерируем блоки из консоли](https://t.me/fluttermiddlepodcast/423) +— [bloc_lint](https://t.me/fluttermiddlepodcast/461) +— [bloc_test](https://t.me/fluttermiddlepodcast/463) + +### Полезное + +— [flutter_bloc на собеседованиях](https://t.me/fluttermiddlepodcast/282) +— [VS Code для разработки Flutter-приложений](https://t.me/fluttermiddlepodcast/327) ## Запуск diff --git a/test/features/users/users_bloc_test.dart b/test/features/users/users_bloc_test.dart index 28bf102..b35589e 100644 --- a/test/features/users/users_bloc_test.dart +++ b/test/features/users/users_bloc_test.dart @@ -9,7 +9,31 @@ import 'package:mocktail/mocktail.dart'; import '../../mocks/hydrated_storage_mock.dart'; -class MockUsersRepository extends Mock implements UsersRepository {} +class FakeUsersRepository extends Fake implements UsersRepository { + final List _allUsers; + + FakeUsersRepository(this._allUsers); + + @override + Future<(List?, String?)> fetchUsers({ + int limit = 30, + int page = 0, + }) async { + final start = page * limit; + final end = start + limit; + + if (start >= _allUsers.length) { + return ([], null); + } + + final pageUsers = _allUsers.sublist( + start, + end.clamp(0, _allUsers.length), + ); + + return (pageUsers, null); + } +} void main() { group( @@ -19,48 +43,11 @@ void main() { setUp( () { - usersRepository = MockUsersRepository(); - - when( - () => usersRepository.fetchUsers( - limit: 30, - page: 0, - ), - ).thenAnswer( - (_) => Future.value( - ( - _testUsers, - null, - ), - ), - ); - - when( - () => usersRepository.fetchUsers( - limit: 30, - page: 1, - ), - ).thenAnswer( - (_) => Future.value( - ( - _testUsers, - null, - ), - ), - ); - - when( - () => usersRepository.fetchUsers( - limit: 30, - page: 2, - ), - ).thenAnswer( - (_) => Future.value( - ( - [], - null, - ), - ), + usersRepository = FakeUsersRepository( + [ + ..._testUsers, + ..._testUsers, + ], ); }, ); From 649a3fb7f76a58d50f8114916b7df661de3fe4f8 Mon Sep 17 00:00:00 2001 From: fluttermiddlepodcast Date: Sat, 31 Jan 2026 15:31:30 +0300 Subject: [PATCH 2/3] updated docs --- README.md | 53 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 6400dc6..1d450b1 100644 --- a/README.md +++ b/README.md @@ -5,53 +5,60 @@ ## Описание -Небольшой проект для демонстрации возможностей [bloc](https://pub.dev/packages/bloc) и [flutter_bloc](https://pub.dev/packages/flutter_bloc). +Небольшой проект для демонстрации возможностей [bloc](https://pub.dev/packages/bloc) +и [flutter_bloc](https://pub.dev/packages/flutter_bloc). ## Материалы из репозитория ### Основы -— [Flutter Developer Talks #12 - BLoC](https://podcasts.apple.com/ru/podcast/flutter-developer-talks/id1648922484?i=1000644267848) -— [Flutter Developer Learn #1 - Дополнение к выпуску про базу BLoC](https://t.me/fluttermiddlepodcast/173) -— [Flutter Developer Learn #2 - BlocBuilder](https://youtu.be/98iF13KKdss) -— [Flutter Developer Learn #3 - Реализация состояний в BLoC](https://youtu.be/YBLzMV9dVmI) -— [Flutter Developer Learn #4 - BlocListener](https://t.me/fluttermiddlepodcast/277) -— [Flutter Developer Learn #5 - Cubit](https://t.me/fluttermiddlepodcast/279) -— [Flutter Developer Learn #8 - Как не нужно выстраивать коммуникацию между блоками](https://t.me/fluttermiddlepodcast/300) -— [Flutter Developer Learn #10 - BlocConsumer 2](https://t.me/fluttermiddlepodcast/338) +- [Flutter Developer Talks #12 - BLoC](https://podcasts.apple.com/ru/podcast/flutter-developer-talks/id1648922484?i=1000644267848) +- [Flutter Developer Learn #1 - Дополнение к выпуску про базу BLoC](https://t.me/fluttermiddlepodcast/173) +- [Flutter Developer Learn #2 - BlocBuilder](https://youtu.be/98iF13KKdss) +- [Flutter Developer Learn #3 - Реализация состояний в BLoC](https://youtu.be/YBLzMV9dVmI) +- [Flutter Developer Learn #4 - BlocListener](https://t.me/fluttermiddlepodcast/277) +- [Flutter Developer Learn #5 - Cubit](https://t.me/fluttermiddlepodcast/279) +- [Flutter Developer Learn #8 - Как не нужно выстраивать коммуникацию между блоками](https://t.me/fluttermiddlepodcast/300) +- [Flutter Developer Learn #10 - BlocConsumer 2](https://t.me/fluttermiddlepodcast/338) ### Продакшн -— [Flutter Developer Learn #6 - feature-first и layer-first подходы для организации Flutter-проектов](https://t.me/fluttermiddlepodcast/281) -— [bloc_concurrency](https://t.me/fluttermiddlepodcast/379) -— [Шиммеры / Скелетоны](https://t.me/fluttermiddlepodcast/391) -— [bloc + пагинация = ❤️](https://t.me/fluttermiddlepodcast/421) -— [hydrated_bloc: сохраняем состояние блоков](https://t.me/fluttermiddlepodcast/426) -— [replay_bloc: откатываем состояния блоков и кубитов](https://t.me/fluttermiddlepodcast/427) +- [Flutter Developer Learn #6 - feature-first и layer-first подходы для организации Flutter-проектов](https://t.me/fluttermiddlepodcast/281) +- [bloc_concurrency](https://t.me/fluttermiddlepodcast/379) +- [Шиммеры / Скелетоны](https://t.me/fluttermiddlepodcast/391) +- [bloc + пагинация = ❤️](https://t.me/fluttermiddlepodcast/421) +- [hydrated_bloc: сохраняем состояние блоков](https://t.me/fluttermiddlepodcast/426) +- [replay_bloc: откатываем состояния блоков и кубитов](https://t.me/fluttermiddlepodcast/427) ### Тулинг -— [Flutter Developer Learn #7 - Генерация шаблонного кода / mason](https://t.me/fluttermiddlepodcast/297) -— [bloc_tools: генерируем блоки из консоли](https://t.me/fluttermiddlepodcast/423) -— [bloc_lint](https://t.me/fluttermiddlepodcast/461) -— [bloc_test](https://t.me/fluttermiddlepodcast/463) +- [Flutter Developer Learn #7 - Генерация шаблонного кода / mason](https://t.me/fluttermiddlepodcast/297) +- [bloc_tools: генерируем блоки из консоли](https://t.me/fluttermiddlepodcast/423) +- [bloc_lint](https://t.me/fluttermiddlepodcast/461) +- [bloc_test](https://t.me/fluttermiddlepodcast/463) ### Полезное -— [flutter_bloc на собеседованиях](https://t.me/fluttermiddlepodcast/282) -— [VS Code для разработки Flutter-приложений](https://t.me/fluttermiddlepodcast/327) +- [flutter_bloc на собеседованиях](https://t.me/fluttermiddlepodcast/282) +- [VS Code для разработки Flutter-приложений](https://t.me/fluttermiddlepodcast/327) ## Запуск ### fvm В проекте используется [fvm](https://fvm.app/) в качестве менеджера версий Флаттера. -[fvm_config.json](./.fvm/fvm_config.json) содержит в себе актуальный конфиг, достаточно лишь выполнить `fvm use`. +[fvm_config.json](./.fvm/fvm_config.json) содержит в себе актуальный конфиг. + +Во время настройки проекта выполните: + +```shell +fvm use +``` ### Без fvm В [fvm_config.json](./.fvm/fvm_config.json) указана версия Флаттера, которую необходимо установить для работы с -проектом. Сделать это можно любым удобным для вас способом, но лучше использовать `fvm`. +проектом. Сделать это можно любым удобным для вас способом, но лучше использовать [fvm](https://fvm.app/). ### Запуск From 5902870073489910c4220b2d71fd45702b2afa5e Mon Sep 17 00:00:00 2001 From: fluttermiddlepodcast Date: Sat, 31 Jan 2026 15:36:21 +0300 Subject: [PATCH 3/3] fixed analyzer issues --- test/features/users/users_bloc_test.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/test/features/users/users_bloc_test.dart b/test/features/users/users_bloc_test.dart index b35589e..918cd4f 100644 --- a/test/features/users/users_bloc_test.dart +++ b/test/features/users/users_bloc_test.dart @@ -5,7 +5,6 @@ import 'package:bloc_example/features/users/model/user.dart'; import 'package:bloc_example/features/users/repository/users_repository.dart'; import 'package:bloc_test/bloc_test.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:mocktail/mocktail.dart'; import '../../mocks/hydrated_storage_mock.dart';