이벤트 가져오기 위젯 테스트 추가 및 테스트 훅 도입

This commit is contained in:
2025-09-12 06:33:44 +09:00
parent 107abc963f
commit a5f2544d11
121 changed files with 39277 additions and 3911 deletions
@@ -0,0 +1,136 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:provider/provider.dart';
import 'package:lanebow/models/participant_model.dart';
import 'package:lanebow/services/event_service.dart';
import 'package:lanebow/screens/club/participant_form_screen.dart';
import '../../utils/event_bus_test_utils.dart';
import 'package:lanebow/utils/test_utils.dart';
// 공통 StubEventService 사용
import '../../utils/stub_event_service.dart';
import '../../utils/dummy_test_data.dart';
void main() {
late EventService stubEventService;
setUp(() async {
// EventBus 테스트 환경 초기화 (플래키 방지)
TestUtils.setTestMode(true);
await EventBusTestUtils.setUp('participant_form_screen_test');
stubEventService = StubEventService();
});
tearDown(() async {
await EventBusTestUtils.tearDown();
});
// 로컬 더미 생성기 제거: DummyTestData 공용 유틸 사용
// 위젯 빌더
Widget createParticipantForm({
required String eventId,
Participant? participant,
}) {
return MaterialApp(
home: ChangeNotifierProvider<EventService>.value(
value: stubEventService,
child: ParticipantFormScreen(
eventId: eventId,
participant: participant,
),
),
);
}
group('ParticipantFormScreen 위젯 테스트', () {
testWidgets('새 참가자 추가 모드: 필수값 입력 후 저장 플로우', (tester) async {
await tester.pumpWidget(createParticipantForm(eventId: 'event1'));
await tester.pumpAndSettle();
// 이름 입력 (필수)
final nameField = find.widgetWithText(TextFormField, '이름 *');
expect(nameField, findsOneWidget);
await tester.enterText(nameField, '홍길동');
// 저장 아이콘 버튼 탭
await tester.tap(find.byIcon(Icons.save));
await tester.pump(const Duration(milliseconds: 300));
await tester.pump(const Duration(seconds: 1));
// then: 화면이 pop 되었는지 확인 (성공 시 Navigator.pop(true) 호출)
expect(find.byType(ParticipantFormScreen), findsNothing);
});
testWidgets('참가자 수정 모드: 수정 후 저장 플로우', (tester) async {
// given
final existing = DummyTestData.participants(eventId: 'event1', count: 1, status: '확인됨').first;
await tester.pumpWidget(createParticipantForm(eventId: 'event1', participant: existing));
await tester.pumpAndSettle();
// 제목이 수정 모드로 표시되는지 확인
expect(find.text('참가자 수정'), findsWidgets);
// 이름 변경
final nameField = find.widgetWithText(TextFormField, '이름 *');
expect(nameField, findsOneWidget);
await tester.enterText(nameField, '수정된이름');
// 저장
await tester.tap(find.byIcon(Icons.save));
await tester.pump(const Duration(milliseconds: 300));
await tester.pump(const Duration(seconds: 1));
// then: 화면이 pop 되었는지 확인
expect(find.byType(ParticipantFormScreen), findsNothing);
});
testWidgets('실패 케이스(추가): 스낵바 에러 노출, 로딩 해제, pop 미호출', (tester) async {
// given
(stubEventService as StubEventService).throwOnAddParticipant = true;
await tester.pumpWidget(createParticipantForm(eventId: 'event1'));
await tester.pumpAndSettle();
// 이름 입력
final nameField = find.widgetWithText(TextFormField, '이름 *');
expect(nameField, findsOneWidget);
await tester.enterText(nameField, '실패사례');
// when: 저장 클릭
await tester.tap(find.byIcon(Icons.save));
await tester.pump(const Duration(milliseconds: 300));
await tester.pump(const Duration(seconds: 1));
// then: 화면이 여전히 존재 (pop 미호출)
expect(find.byType(ParticipantFormScreen), findsOneWidget);
// 에러 스낵바 노출
expect(find.textContaining('참가자 저장에 실패했습니다'), findsOneWidget);
});
testWidgets('실패 케이스(수정): 스낵바 에러 노출, 로딩 해제, pop 미호출', (tester) async {
// given
(stubEventService as StubEventService).throwOnUpdateParticipant = true;
final existing = DummyTestData.participants(eventId: 'event1', count: 1, status: '확인됨').first;
await tester.pumpWidget(createParticipantForm(eventId: 'event1', participant: existing));
await tester.pumpAndSettle();
// 이름 변경
final nameField = find.widgetWithText(TextFormField, '이름 *');
expect(nameField, findsOneWidget);
await tester.enterText(nameField, '변경실패');
// when: 저장 클릭
await tester.tap(find.byIcon(Icons.save));
await tester.pump(const Duration(milliseconds: 300));
await tester.pump(const Duration(seconds: 1));
// then
expect(find.byType(ParticipantFormScreen), findsOneWidget);
expect(find.textContaining('참가자 저장에 실패했습니다'), findsOneWidget);
});
});
}