test(helpers): 테스트 헬퍼 및 Fake 스토리지 추가
- TestSetup 클래스 추가 (SharedPreferences 모킹, 싱글톤 정리) - FakeHallOfFameStorage: 메모리 기반 명예의 전당 저장소 - FakeStatisticsStorage: 메모리 기반 통계 저장소 - path_provider 의존성 없이 테스트 가능하도록 개선
This commit is contained in:
@@ -4,12 +4,16 @@ import 'package:asciineverdie/src/core/engine/reward_service.dart';
|
|||||||
import 'package:asciineverdie/src/core/model/combat_state.dart';
|
import 'package:asciineverdie/src/core/model/combat_state.dart';
|
||||||
import 'package:asciineverdie/src/core/model/combat_stats.dart';
|
import 'package:asciineverdie/src/core/model/combat_stats.dart';
|
||||||
import 'package:asciineverdie/src/core/model/game_state.dart';
|
import 'package:asciineverdie/src/core/model/game_state.dart';
|
||||||
|
import 'package:asciineverdie/src/core/model/game_statistics.dart';
|
||||||
|
import 'package:asciineverdie/src/core/model/hall_of_fame.dart';
|
||||||
import 'package:asciineverdie/src/core/model/monetization_state.dart';
|
import 'package:asciineverdie/src/core/model/monetization_state.dart';
|
||||||
import 'package:asciineverdie/src/core/model/monster_combat_stats.dart';
|
import 'package:asciineverdie/src/core/model/monster_combat_stats.dart';
|
||||||
import 'package:asciineverdie/src/core/model/pq_config.dart';
|
import 'package:asciineverdie/src/core/model/pq_config.dart';
|
||||||
|
import 'package:asciineverdie/src/core/storage/hall_of_fame_storage.dart';
|
||||||
import 'package:asciineverdie/src/core/storage/save_manager.dart';
|
import 'package:asciineverdie/src/core/storage/save_manager.dart';
|
||||||
import 'package:asciineverdie/src/core/storage/save_repository.dart';
|
import 'package:asciineverdie/src/core/storage/save_repository.dart';
|
||||||
import 'package:asciineverdie/src/core/storage/save_service.dart';
|
import 'package:asciineverdie/src/core/storage/save_service.dart';
|
||||||
|
import 'package:asciineverdie/src/core/storage/statistics_storage.dart';
|
||||||
import 'package:asciineverdie/src/core/util/balance_constants.dart';
|
import 'package:asciineverdie/src/core/util/balance_constants.dart';
|
||||||
|
|
||||||
export 'package:asciineverdie/src/core/storage/save_repository.dart'
|
export 'package:asciineverdie/src/core/storage/save_repository.dart'
|
||||||
@@ -201,3 +205,91 @@ class MockFactories {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 테스트용 Fake HallOfFameStorage
|
||||||
|
///
|
||||||
|
/// 파일 시스템 접근 없이 메모리에서 동작
|
||||||
|
class FakeHallOfFameStorage extends HallOfFameStorage {
|
||||||
|
HallOfFame _hallOfFame = HallOfFame.empty();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<HallOfFame> load() async => _hallOfFame;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> save(HallOfFame hallOfFame) async {
|
||||||
|
_hallOfFame = hallOfFame;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> addEntry(HallOfFameEntry entry) async {
|
||||||
|
_hallOfFame = _hallOfFame.addEntry(entry);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> deleteEntry(String id) async {
|
||||||
|
_hallOfFame = _hallOfFame.removeEntry(id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> clear() async {
|
||||||
|
_hallOfFame = HallOfFame.empty();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 테스트용 Fake StatisticsStorage
|
||||||
|
///
|
||||||
|
/// 파일 시스템 접근 없이 메모리에서 동작
|
||||||
|
class FakeStatisticsStorage extends StatisticsStorage {
|
||||||
|
CumulativeStatistics _stats = CumulativeStatistics.empty();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<CumulativeStatistics> loadCumulative() async => _stats;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> saveCumulative(CumulativeStatistics stats) async {
|
||||||
|
_stats = stats;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> mergeSession(SessionStatistics session) async {
|
||||||
|
_stats = _stats.mergeSession(session);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> updateHighestLevel(int level) async {
|
||||||
|
if (level <= _stats.highestLevel) return true;
|
||||||
|
_stats = _stats.updateHighestLevel(level);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> updateHighestGold(int gold) async {
|
||||||
|
if (gold <= _stats.highestGoldHeld) return true;
|
||||||
|
_stats = _stats.updateHighestGold(gold);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> recordGameStart() async {
|
||||||
|
_stats = _stats.recordGameStart();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> recordGameComplete() async {
|
||||||
|
_stats = _stats.recordGameComplete();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> clear() async {
|
||||||
|
_stats = CumulativeStatistics.empty();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
31
test/helpers/test_setup.dart
Normal file
31
test/helpers/test_setup.dart
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import 'package:asciineverdie/src/core/audio/audio_service.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
/// 위젯 테스트에서 사용하는 공통 셋업/정리 유틸리티
|
||||||
|
///
|
||||||
|
/// 싱글톤 서비스들이 테스트 간 상태를 공유하지 않도록 정리합니다.
|
||||||
|
class TestSetup {
|
||||||
|
TestSetup._();
|
||||||
|
|
||||||
|
/// SharedPreferences 모킹 설정
|
||||||
|
///
|
||||||
|
/// setUpAll에서 호출하여 SharedPreferences 의존성 제거
|
||||||
|
static void mockSharedPreferences() {
|
||||||
|
final binding = TestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
binding.defaultBinaryMessenger.setMockMethodCallHandler(
|
||||||
|
const MethodChannel('plugins.flutter.io/shared_preferences'),
|
||||||
|
(call) async {
|
||||||
|
if (call.method == 'getAll') return <String, Object>{};
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 모든 싱글톤 서비스 정리
|
||||||
|
///
|
||||||
|
/// tearDown에서 호출하여 타이머 및 리소스 정리
|
||||||
|
static void resetAllServices() {
|
||||||
|
AudioService.resetAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user