import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; import 'package:superport/services/equipment_service.dart'; import 'package:superport/services/company_service.dart'; import 'package:superport/services/warehouse_service.dart'; import 'package:superport/models/equipment_unified_model.dart'; import 'package:superport/data/models/equipment/equipment_response.dart'; import 'package:superport/data/models/equipment/equipment_io_response.dart'; import 'package:superport/data/models/company/company_dto.dart'; import 'package:superport/data/models/warehouse/warehouse_dto.dart'; import 'package:superport/models/company_model.dart'; import 'package:superport/models/warehouse_location_model.dart'; import 'package:superport/models/address_model.dart'; import '../helpers/simple_mock_services.mocks.dart'; /// 간단한 장비 입고 통합 테스트 /// /// 이 테스트는 Mock 서비스를 사용하여 장비 입고 프로세스를 검증합니다. void main() { late MockEquipmentService mockEquipmentService; late MockCompanyService mockCompanyService; late MockWarehouseService mockWarehouseService; setUp(() { mockEquipmentService = MockEquipmentService(); mockCompanyService = MockCompanyService(); mockWarehouseService = MockWarehouseService(); }); group('장비 입고 프로세스 테스트', () { test('정상적인 장비 입고 프로세스', () async { // Given: 테스트 데이터 준비 const testCompanyId = 1; const testWarehouseId = 1; const testEquipmentId = 1; final testCompany = Company( id: testCompanyId, name: 'Test Company', address: Address( region: '서울시 강남구', detailAddress: '테스트 주소', ), contactName: 'Test Contact', contactPhone: '010-1234-5678', contactEmail: 'test@test.com', ); final testWarehouse = WarehouseLocation( id: testWarehouseId, name: 'Test Warehouse', address: Address( region: '서울시 강남구', detailAddress: '테스트 주소', ), remark: '테스트 창고', ); final testEquipment = Equipment( id: testEquipmentId, manufacturer: 'Samsung', name: 'Galaxy Book Pro', category: '노트북', subCategory: '업무용', subSubCategory: '고성능', serialNumber: 'SN123456', quantity: 1, ); final expectedEquipmentResponse = EquipmentResponse( id: testEquipmentId, equipmentNumber: 'EQ-001', category1: '노트북', manufacturer: 'Samsung', status: 'I', // 입고 상태 createdAt: DateTime.now(), updatedAt: DateTime.now(), ); final expectedInResult = EquipmentIoResponse( success: true, message: '장비가 성공적으로 입고되었습니다.', transactionId: 1, equipmentId: testEquipmentId, transactionType: 'IN', quantity: 1, transactionDate: DateTime.now(), ); // When: Mock 동작 설정 when(mockCompanyService.getCompanyDetail(testCompanyId)) .thenAnswer((_) async => testCompany); when(mockWarehouseService.getWarehouseLocationById(testWarehouseId)) .thenAnswer((_) async => testWarehouse); when(mockEquipmentService.createEquipment(any)) .thenAnswer((_) async => testEquipment); when(mockEquipmentService.equipmentIn( equipmentId: testEquipmentId, quantity: 1, warehouseLocationId: testWarehouseId, notes: anyNamed('notes'), )).thenAnswer((_) async => expectedInResult); // Then: 테스트 실행 // 1. 회사 확인 final company = await mockCompanyService.getCompanyDetail(testCompanyId); expect(company, isNotNull); expect(company.id, equals(testCompanyId)); // 2. 창고 확인 final warehouse = await mockWarehouseService.getWarehouseLocationById(testWarehouseId); expect(warehouse, isNotNull); expect(warehouse.id, equals(testWarehouseId)); // 3. 장비 생성 final createdEquipment = await mockEquipmentService.createEquipment(testEquipment); expect(createdEquipment, isNotNull); expect(createdEquipment.id, equals(testEquipmentId)); // 4. 장비 입고 final inResult = await mockEquipmentService.equipmentIn( equipmentId: createdEquipment.id!, quantity: 1, warehouseLocationId: testWarehouseId, notes: '테스트 입고', ); expect(inResult, isNotNull); expect(inResult.success, isTrue); expect(inResult.transactionType, equals('IN')); // 5. Mock 호출 검증 verify(mockCompanyService.getCompanyDetail(testCompanyId)).called(1); verify(mockWarehouseService.getWarehouseLocationById(testWarehouseId)).called(1); verify(mockEquipmentService.createEquipment(any)).called(1); verify(mockEquipmentService.equipmentIn( equipmentId: testEquipmentId, quantity: 1, warehouseLocationId: testWarehouseId, notes: '테스트 입고', )).called(1); }); test('필수 필드 누락 시 장비 생성 실패', () async { // Given: 필수 필드가 누락된 장비 final incompleteEquipment = Equipment( manufacturer: '', // 빈 제조사 name: '', // 빈 이름 category: '', // 빈 카테고리 subCategory: '', subSubCategory: '', quantity: 1, ); // When: Mock이 예외를 던지도록 설정 when(mockEquipmentService.createEquipment(any)) .thenThrow(Exception('필수 필드가 누락되었습니다.')); // Then: 예외 발생 확인 expect( () => mockEquipmentService.createEquipment(incompleteEquipment), throwsException, ); }); test('존재하지 않는 창고로 입고 시도 시 실패', () async { // Given const nonExistentWarehouseId = 999; const testEquipmentId = 1; // When: Mock이 예외를 던지도록 설정 when(mockWarehouseService.getWarehouseLocationById(nonExistentWarehouseId)) .thenThrow(Exception('창고를 찾을 수 없습니다.')); when(mockEquipmentService.equipmentIn( equipmentId: testEquipmentId, quantity: 1, warehouseLocationId: nonExistentWarehouseId, notes: anyNamed('notes'), )).thenThrow(Exception('유효하지 않은 창고 ID입니다.')); // Then: 예외 발생 확인 expect( () => mockWarehouseService.getWarehouseLocationById(nonExistentWarehouseId), throwsException, ); expect( () => mockEquipmentService.equipmentIn( equipmentId: testEquipmentId, quantity: 1, warehouseLocationId: nonExistentWarehouseId, notes: '테스트', ), throwsException, ); }); }); group('장비 입고 시나리오별 테스트', () { test('대량 장비 입고 처리', () async { // Given: 여러 개의 장비 final equipmentList = List.generate(10, (index) => Equipment( id: index + 1, manufacturer: 'Manufacturer $index', name: 'Equipment $index', category: '카테고리', subCategory: '서브카테고리', subSubCategory: '상세카테고리', quantity: 1, )); // When: 각 장비에 대해 Mock 설정 for (final equipment in equipmentList) { when(mockEquipmentService.createEquipment(any)) .thenAnswer((_) async => equipment); when(mockEquipmentService.equipmentIn( equipmentId: equipment.id!, quantity: 1, warehouseLocationId: 1, notes: anyNamed('notes'), )).thenAnswer((_) async => EquipmentIoResponse( success: true, message: '입고 성공', transactionId: equipment.id!, equipmentId: equipment.id!, transactionType: 'IN', quantity: 1, transactionDate: DateTime.now(), )); } // Then: 모든 장비 입고 처리 var successCount = 0; for (final equipment in equipmentList) { final created = await mockEquipmentService.createEquipment(equipment); final result = await mockEquipmentService.equipmentIn( equipmentId: created.id!, quantity: 1, warehouseLocationId: 1, notes: '대량 입고', ); if (result.success) { successCount++; } } expect(successCount, equals(10)); }); }); }