import'package:dependencies/dependencies.dart';import'package:feature_home/src/data/repository/home_repository.dart';import'package:feature_home/src/domain/entity/user.dart';import'package:flutter_test/flutter_test.dart';import'package:mockito/annotations.dart';import'package:mockito/mockito.dart';import'home_repository_test.mocks.dart';@GenerateNiceMocks([MockSpec<HomeApiClient>(),MockSpec<HomeLocalDataSource>(),])voidmain(){lateHomeRepository repository;lateMockHomeApiClient mockApiClient;lateMockHomeLocalDataSource mockLocalDataSource;setUp((){
mockApiClient =MockHomeApiClient();
mockLocalDataSource =MockHomeLocalDataSource();
repository =HomeRepository(
apiClient: mockApiClient,
localDataSource: mockLocalDataSource,);});tearDown((){reset(mockApiClient);reset(mockLocalDataSource);});group('HomeRepository.getUser',(){const tUserId =1;const tUserDto =UserDto(id: tUserId, name:'ํ๊ธธ๋', email:'hong@example.com');const tUser =User(id: tUserId, name:'ํ๊ธธ๋', email:'hong@example.com');test('should return User when API call is successful',()async{// Arrangewhen(mockApiClient.getUser(tUserId)).thenAnswer((_)async=> tUserDto);// Actfinal result =await repository.getUser(tUserId);// Assertexpect(result,constRight<Failure, User>(tUser));verify(mockApiClient.getUser(tUserId)).called(1);});test('should cache data locally when API call is successful',()async{// Arrangewhen(mockApiClient.getUser(tUserId)).thenAnswer((_)async=> tUserDto);when(mockLocalDataSource.cacheUser(any)).thenAnswer((_)async{});// Actawait repository.getUser(tUserId);// Assertverify(mockLocalDataSource.cacheUser(tUserDto)).called(1);});test('should return cached data when API call fails',()async{// Arrangewhen(mockApiClient.getUser(tUserId)).thenThrow(Exception('Network error'));when(mockLocalDataSource.getCachedUser(tUserId)).thenAnswer((_)async=> tUserDto);// Actfinal result =await repository.getUser(tUserId);// Assertexpect(result,constRight<Failure, User>(tUser));verify(mockLocalDataSource.getCachedUser(tUserId)).called(1);});test('should return Failure when both API and cache fail',()async{// Arrangewhen(mockApiClient.getUser(tUserId)).thenThrow(Exception('Network error'));when(mockLocalDataSource.getCachedUser(tUserId)).thenAnswer((_)async=>null);// Actfinal result =await repository.getUser(tUserId);// Assertexpect(result.isLeft(),true);
result.fold((failure)=>expect(failure,isA<CacheFailure>()),(_)=>fail('Should return Left'),);});});}
import'package:dependencies/dependencies.dart';import'package:flutter_test/flutter_test.dart';/// Either ๊ฒฐ๊ณผ ๊ฒ์ฆ ํ์ฅ
extensionEitherTestExtension<L, R>onEither<L, R>{/// Left ๊ฐ ์ถ์ถ (ํ ์คํธ์ฉ)
LgetLeft(){returnfold((l)=> l,(_)=>throwException('Expected Left but got Right'));}/// Right ๊ฐ ์ถ์ถ (ํ ์คํธ์ฉ)
RgetRight(){returnfold((_)=>throwException('Expected Right but got Left'),(r)=> r);}}/// Either ๋งค์ฒ
MatcherisRightWith<R>(R expected){returnpredicate<Either<dynamic, R>>((either)=> either.fold((_)=>false,(r)=> r == expected),'is Right with $expected',);}MatcherisLeftWith<L>(L expected){returnpredicate<Either<L, dynamic>>((either)=> either.fold((l)=> l == expected,(_)=>false),'is Left with $expected',);}MatcherisLeftOfType<L>(){returnpredicate<Either<L, dynamic>>((either)=> either.fold((l)=> l isL,(_)=>false),'is Left of type $L',);}