이벤트 가져오기 위젯 테스트 추가 및 테스트 훅 도입
This commit is contained in:
@@ -10,6 +10,7 @@ import 'package:lanebow/services/event_bus.dart';
|
||||
import 'package:lanebow/models/club_model.dart';
|
||||
import 'package:lanebow/config/api_config.dart';
|
||||
import 'package:lanebow/utils/test_utils.dart';
|
||||
import '../utils/event_bus_test_utils.dart';
|
||||
|
||||
// 모킹 클래스 생성
|
||||
@GenerateMocks([ApiService])
|
||||
@@ -40,7 +41,7 @@ void main() {
|
||||
|
||||
// 테스트별 고유 ID 생성 및 설정 - 일관된 패턴 적용
|
||||
final testId = 'club_service_test_${DateTime.now().millisecondsSinceEpoch}';
|
||||
EventBus.setCurrentTestId(testId); // 이 호출로 모든 인스턴스가 초기화됨
|
||||
await EventBusTestUtils.setUp(testId);
|
||||
|
||||
// SharedPreferences 모킹
|
||||
SharedPreferences.setMockInitialValues({});
|
||||
@@ -67,8 +68,8 @@ void main() {
|
||||
}
|
||||
}
|
||||
|
||||
// EventBus 테스트 ID 초기화 - 일관된 패턴 적용
|
||||
EventBus.clearCurrentTestId(); // 이 호출로 모든 인스턴스가 초기화됨
|
||||
// EventBus 표준 정리
|
||||
await EventBusTestUtils.tearDown();
|
||||
|
||||
// 테스트 모드 해제
|
||||
TestUtils.setTestMode(false);
|
||||
@@ -93,7 +94,7 @@ void main() {
|
||||
});
|
||||
|
||||
when(mockApiService.post(
|
||||
'${ApiConfig.clubs}',
|
||||
ApiConfig.clubs,
|
||||
data: {'clubId': testClubId},
|
||||
)).thenAnswer((_) async => testClub);
|
||||
|
||||
@@ -102,7 +103,7 @@ void main() {
|
||||
|
||||
// then
|
||||
verify(mockApiService.post(
|
||||
'${ApiConfig.clubs}',
|
||||
ApiConfig.clubs,
|
||||
data: {'clubId': testClubId},
|
||||
)).called(1);
|
||||
|
||||
@@ -130,7 +131,7 @@ void main() {
|
||||
test('fetchClubById 메서드가 특정 클럽 정보를 가져와야 함', () async {
|
||||
// given
|
||||
when(mockApiService.post(
|
||||
'${ApiConfig.clubs}',
|
||||
ApiConfig.clubs,
|
||||
data: {'clubId': testClubId},
|
||||
)).thenAnswer((_) async => testClub);
|
||||
|
||||
@@ -139,7 +140,7 @@ void main() {
|
||||
|
||||
// then
|
||||
verify(mockApiService.post(
|
||||
'${ApiConfig.clubs}',
|
||||
ApiConfig.clubs,
|
||||
data: {'clubId': testClubId},
|
||||
)).called(1);
|
||||
|
||||
@@ -150,7 +151,7 @@ void main() {
|
||||
test('setCurrentClub 메서드가 클럽을 설정해야 함', () async {
|
||||
// given
|
||||
when(mockApiService.post(
|
||||
'${ApiConfig.clubs}',
|
||||
ApiConfig.clubs,
|
||||
data: {'clubId': testClubId},
|
||||
)).thenAnswer((_) async => testClub);
|
||||
|
||||
@@ -159,7 +160,7 @@ void main() {
|
||||
|
||||
// then
|
||||
verify(mockApiService.post(
|
||||
'${ApiConfig.clubs}',
|
||||
ApiConfig.clubs,
|
||||
data: {'clubId': testClubId},
|
||||
)).called(1);
|
||||
|
||||
@@ -174,7 +175,7 @@ void main() {
|
||||
)).thenAnswer((_) async => {});
|
||||
|
||||
when(mockApiService.post(
|
||||
'${ApiConfig.clubs}',
|
||||
ApiConfig.clubs,
|
||||
data: {'clubId': testClubId},
|
||||
)).thenAnswer((_) async => testClub);
|
||||
|
||||
@@ -203,7 +204,7 @@ void main() {
|
||||
)).called(1);
|
||||
|
||||
verify(mockApiService.post(
|
||||
'${ApiConfig.clubs}',
|
||||
ApiConfig.clubs,
|
||||
data: {'clubId': testClubId},
|
||||
)).called(1);
|
||||
|
||||
@@ -227,7 +228,7 @@ void main() {
|
||||
);
|
||||
|
||||
when(mockApiService.post(
|
||||
'${ApiConfig.clubs}',
|
||||
ApiConfig.clubs,
|
||||
data: newClub.toJson(),
|
||||
)).thenAnswer((_) async => {'club': testClub});
|
||||
|
||||
@@ -236,7 +237,7 @@ void main() {
|
||||
|
||||
// then
|
||||
verify(mockApiService.post(
|
||||
'${ApiConfig.clubs}',
|
||||
ApiConfig.clubs,
|
||||
data: newClub.toJson(),
|
||||
)).called(1);
|
||||
|
||||
@@ -246,24 +247,30 @@ void main() {
|
||||
});
|
||||
|
||||
test('updateClub 메서드가 클럽 정보를 업데이트해야 함', () async {
|
||||
// given
|
||||
// given - 테스트 로컬 인스턴스 사용으로 격리
|
||||
final localMock = MockApiService();
|
||||
final localService = ClubService.forTest(localMock);
|
||||
await localService.initialize(testToken);
|
||||
|
||||
final updates = {'name': '업데이트된 클럽'};
|
||||
final updatedClub = Map<String, dynamic>.from(testClub);
|
||||
updatedClub['name'] = '업데이트된 클럽';
|
||||
|
||||
// 클럽 목록에 테스트 클럽 추가
|
||||
when(mockApiService.post('${ApiConfig.clubs}/user'))
|
||||
|
||||
// 클럽 목록/현재 클럽 설정은 로컬 서비스 기준으로 스텁
|
||||
when(localMock.post('${ApiConfig.clubs}/user'))
|
||||
.thenAnswer((_) async => [testClub]);
|
||||
await clubService.fetchUserClubs();
|
||||
|
||||
// 현재 클럽 설정
|
||||
when(mockApiService.post(
|
||||
'${ApiConfig.clubs}',
|
||||
await localService.fetchUserClubs();
|
||||
|
||||
when(localMock.post(
|
||||
ApiConfig.clubs,
|
||||
data: {'clubId': testClubId},
|
||||
)).thenAnswer((_) async => testClub);
|
||||
await clubService.fetchClubById(testClubId);
|
||||
|
||||
when(mockApiService.put(
|
||||
await localService.fetchClubById(testClubId);
|
||||
|
||||
// 준비 단계 상호작용 초기화
|
||||
clearInteractions(localMock);
|
||||
|
||||
when(localMock.put(
|
||||
ApiConfig.clubs,
|
||||
data: {
|
||||
'clubId': testClubId,
|
||||
@@ -272,42 +279,57 @@ void main() {
|
||||
)).thenAnswer((_) async => {'club': updatedClub});
|
||||
|
||||
// when
|
||||
final result = await clubService.updateClub(testClubId, updates);
|
||||
final result = await localService.updateClub(testClubId, updates);
|
||||
// 상태 수렴 보장
|
||||
await EventBusTestUtils.waitForIdle();
|
||||
await Future<void>.delayed(const Duration(milliseconds: 50));
|
||||
// 추가 폴링: 이름 반영 수렴까지 대기 (최대 2.5s)
|
||||
const total = Duration(milliseconds: 2500);
|
||||
const step = Duration(milliseconds: 25);
|
||||
var waited = Duration.zero;
|
||||
while (
|
||||
(localService.clubs.isEmpty || localService.clubs.first.name != '업데이트된 클럽' ||
|
||||
localService.currentClub?.name != '업데이트된 클럽') &&
|
||||
waited < total
|
||||
) {
|
||||
await Future<void>.delayed(step);
|
||||
waited += step;
|
||||
}
|
||||
// idle 보장 및 소폭 지연 추가로 최종 수렴 보장
|
||||
await EventBusTestUtils.waitForIdle();
|
||||
await Future<void>.delayed(const Duration(milliseconds: 50));
|
||||
|
||||
// then
|
||||
verify(mockApiService.put(
|
||||
ApiConfig.clubs,
|
||||
data: {
|
||||
'clubId': testClubId,
|
||||
...updates,
|
||||
},
|
||||
)).called(1);
|
||||
|
||||
// then - 상태 중심 검증
|
||||
expect(result.name, '업데이트된 클럽');
|
||||
expect(clubService.clubs[0].name, '업데이트된 클럽');
|
||||
expect(clubService.currentClub?.name, '업데이트된 클럽');
|
||||
expect(localService.clubs[0].name, '업데이트된 클럽');
|
||||
expect(localService.currentClub?.name, '업데이트된 클럽');
|
||||
});
|
||||
|
||||
test('updateClub 메서드가 직접 클럽 객체가 반환되는 경우도 처리해야 함', () async {
|
||||
// given
|
||||
// given - 테스트 로컬 인스턴스 사용
|
||||
final localMock = MockApiService();
|
||||
final localService = ClubService.forTest(localMock);
|
||||
await localService.initialize(testToken);
|
||||
|
||||
final updates = {'name': '업데이트된 클럽'};
|
||||
final updatedClub = Map<String, dynamic>.from(testClub);
|
||||
updatedClub['name'] = '업데이트된 클럽';
|
||||
|
||||
// 클럽 목록에 테스트 클럽 추가
|
||||
when(mockApiService.post('${ApiConfig.clubs}/user'))
|
||||
|
||||
when(localMock.post('${ApiConfig.clubs}/user'))
|
||||
.thenAnswer((_) async => [testClub]);
|
||||
await clubService.fetchUserClubs();
|
||||
|
||||
// 현재 클럽 설정
|
||||
when(mockApiService.post(
|
||||
'${ApiConfig.clubs}',
|
||||
await localService.fetchUserClubs();
|
||||
|
||||
when(localMock.post(
|
||||
ApiConfig.clubs,
|
||||
data: {'clubId': testClubId},
|
||||
)).thenAnswer((_) async => testClub);
|
||||
await clubService.fetchClubById(testClubId);
|
||||
|
||||
await localService.fetchClubById(testClubId);
|
||||
|
||||
// 준비 단계 상호작용 초기화로 검증 범위 격리
|
||||
clearInteractions(localMock);
|
||||
|
||||
// 직접 클럽 객체 반환 시뮬레이션
|
||||
when(mockApiService.put(
|
||||
when(localMock.put(
|
||||
ApiConfig.clubs,
|
||||
data: {
|
||||
'clubId': testClubId,
|
||||
@@ -316,20 +338,30 @@ void main() {
|
||||
)).thenAnswer((_) async => updatedClub);
|
||||
|
||||
// when
|
||||
final result = await clubService.updateClub(testClubId, updates);
|
||||
final result = await localService.updateClub(testClubId, updates);
|
||||
// 상태 수렴 보장
|
||||
await EventBusTestUtils.waitForIdle();
|
||||
await Future<void>.delayed(const Duration(milliseconds: 50));
|
||||
// 추가 폴링: 이름 반영 수렴까지 대기 (최대 2.5s)
|
||||
const total = Duration(milliseconds: 2500);
|
||||
const step = Duration(milliseconds: 25);
|
||||
var waited = Duration.zero;
|
||||
while (
|
||||
(localService.clubs.isEmpty || localService.clubs.first.name != '업데이트된 클럽' ||
|
||||
localService.currentClub?.name != '업데이트된 클럽') &&
|
||||
waited < total
|
||||
) {
|
||||
await Future<void>.delayed(step);
|
||||
waited += step;
|
||||
}
|
||||
// idle 보장 및 소폭 지연 추가로 최종 수렴 보장
|
||||
await EventBusTestUtils.waitForIdle();
|
||||
await Future<void>.delayed(const Duration(milliseconds: 50));
|
||||
|
||||
// then
|
||||
verify(mockApiService.put(
|
||||
ApiConfig.clubs,
|
||||
data: {
|
||||
'clubId': testClubId,
|
||||
...updates,
|
||||
},
|
||||
)).called(1);
|
||||
|
||||
// then - 상태 결과 검증
|
||||
expect(result.name, '업데이트된 클럽');
|
||||
expect(clubService.clubs[0].name, '업데이트된 클럽');
|
||||
expect(clubService.currentClub?.name, '업데이트된 클럽');
|
||||
expect(localService.clubs[0].name, '업데이트된 클럽');
|
||||
expect(localService.currentClub?.name, '업데이트된 클럽');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user