test: 테스트 자동화 구현 및 Mock 서비스 오류 수정
- 테스트 패키지 추가 (mockito, golden_toolkit, patrol 등) - 테스트 가이드 문서 작성 (TEST_GUIDE.md) - 테스트 진행 상황 문서 작성 (TEST_PROGRESS.md) - 테스트 헬퍼 클래스 구현 - test_helpers.dart: 기본 테스트 유틸리티 - mock_data_helpers.dart: Mock 데이터 생성 헬퍼 - mock_services.dart: Mock 서비스 설정 (오류 수정 완료) - simple_mock_services.dart: 간단한 Mock 서비스 - 단위 테스트 구현 - CompanyListController 테스트 - EquipmentListController 테스트 - UserListController 테스트 - Widget 테스트 구현 (CompanyListScreen) Mock 서비스 주요 수정사항: - dartz import 추가 - Either 타입 제거 (실제 서비스와 일치하도록) - 메서드 시그니처 수정 (실제 서비스 인터페이스와 일치) - Mock 데이터 생성 메서드 추가 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
113
test/unit/controllers/company_list_controller_test.dart
Normal file
113
test/unit/controllers/company_list_controller_test.dart
Normal file
@@ -0,0 +1,113 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:superport/screens/company/controllers/company_list_controller.dart';
|
||||
import 'package:superport/services/company_service.dart';
|
||||
|
||||
import '../../helpers/test_helpers.dart';
|
||||
import '../../helpers/simple_mock_services.dart';
|
||||
import '../../helpers/simple_mock_services.mocks.dart';
|
||||
import '../../helpers/mock_data_helpers.dart';
|
||||
|
||||
void main() {
|
||||
late CompanyListController controller;
|
||||
late MockMockDataService mockDataService;
|
||||
late MockCompanyService mockCompanyService;
|
||||
late GetIt getIt;
|
||||
|
||||
setUp(() {
|
||||
getIt = setupTestGetIt();
|
||||
mockDataService = MockMockDataService();
|
||||
mockCompanyService = MockCompanyService();
|
||||
|
||||
// GetIt에 CompanyService 등록
|
||||
getIt.registerSingleton<CompanyService>(mockCompanyService);
|
||||
|
||||
// Mock 설정
|
||||
SimpleMockServiceHelpers.setupMockDataServiceMock(mockDataService);
|
||||
SimpleMockServiceHelpers.setupCompanyServiceMock(mockCompanyService);
|
||||
|
||||
controller = CompanyListController(dataService: mockDataService);
|
||||
});
|
||||
|
||||
tearDown(() {
|
||||
controller.dispose();
|
||||
getIt.reset();
|
||||
});
|
||||
|
||||
group('CompanyListController 단위 테스트', () {
|
||||
test('검색 키워드 업데이트 테스트', () async {
|
||||
// Act
|
||||
await controller.updateSearchKeyword('테스트');
|
||||
|
||||
// Assert
|
||||
expect(controller.searchKeyword, '테스트');
|
||||
});
|
||||
|
||||
test('회사 선택/해제 테스트', () {
|
||||
// Act
|
||||
controller.toggleCompanySelection(1);
|
||||
expect(controller.selectedCompanyIds.contains(1), true);
|
||||
|
||||
controller.toggleCompanySelection(1);
|
||||
expect(controller.selectedCompanyIds.contains(1), false);
|
||||
});
|
||||
|
||||
test('전체 선택/해제 테스트', () {
|
||||
// Arrange
|
||||
controller.companies = MockDataHelpers.createMockCompanyList(count: 3);
|
||||
controller.filteredCompanies = controller.companies;
|
||||
|
||||
// Act - 전체 선택
|
||||
controller.toggleSelectAll();
|
||||
expect(controller.selectedCompanyIds.length, 3);
|
||||
|
||||
// Act - 전체 해제
|
||||
controller.toggleSelectAll();
|
||||
expect(controller.selectedCompanyIds.isEmpty, true);
|
||||
});
|
||||
|
||||
test('필터 적용 테스트', () {
|
||||
// Arrange
|
||||
controller.companies = MockDataHelpers.createMockCompanyList(count: 5);
|
||||
controller.searchKeyword = '회사 1';
|
||||
|
||||
// Act
|
||||
controller.applyFilters();
|
||||
|
||||
// Assert
|
||||
expect(controller.filteredCompanies.length, 1);
|
||||
expect(controller.filteredCompanies.first.name, '테스트 회사 1');
|
||||
});
|
||||
|
||||
test('회사 삭제 테스트', () async {
|
||||
// Arrange
|
||||
controller.companies = MockDataHelpers.createMockCompanyList(count: 3);
|
||||
controller.filteredCompanies = controller.companies;
|
||||
|
||||
// Act
|
||||
final result = await controller.deleteCompany(1);
|
||||
|
||||
// Assert
|
||||
expect(result, true);
|
||||
expect(controller.companies.length, 2);
|
||||
expect(controller.companies.any((c) => c.id == 1), false);
|
||||
verify(mockCompanyService.deleteCompany(1)).called(1);
|
||||
});
|
||||
|
||||
test('에러 처리 테스트', () async {
|
||||
// Arrange
|
||||
SimpleMockServiceHelpers.setupCompanyServiceMock(
|
||||
mockCompanyService,
|
||||
getCompaniesSuccess: false,
|
||||
);
|
||||
|
||||
// Act
|
||||
await controller.loadData();
|
||||
|
||||
// Assert
|
||||
expect(controller.error, isNotNull);
|
||||
expect(controller.isLoading, false);
|
||||
});
|
||||
});
|
||||
}
|
||||
132
test/unit/controllers/equipment_list_controller_test.dart
Normal file
132
test/unit/controllers/equipment_list_controller_test.dart
Normal file
@@ -0,0 +1,132 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:superport/screens/equipment/controllers/equipment_list_controller.dart';
|
||||
import 'package:superport/services/equipment_service.dart';
|
||||
|
||||
import '../../helpers/test_helpers.dart';
|
||||
import '../../helpers/simple_mock_services.dart';
|
||||
import '../../helpers/simple_mock_services.mocks.dart';
|
||||
import '../../helpers/mock_data_helpers.dart';
|
||||
|
||||
void main() {
|
||||
late EquipmentListController controller;
|
||||
late MockMockDataService mockDataService;
|
||||
late MockEquipmentService mockEquipmentService;
|
||||
late GetIt getIt;
|
||||
|
||||
setUp(() {
|
||||
getIt = setupTestGetIt();
|
||||
mockDataService = MockMockDataService();
|
||||
mockEquipmentService = MockEquipmentService();
|
||||
|
||||
// GetIt에 EquipmentService 등록
|
||||
getIt.registerSingleton<EquipmentService>(mockEquipmentService);
|
||||
|
||||
// Mock 설정
|
||||
when(mockDataService.getAllEquipments()).thenReturn(
|
||||
MockDataHelpers.createMockUnifiedEquipmentList(count: 5)
|
||||
);
|
||||
|
||||
// EquipmentService mock 설정
|
||||
when(mockEquipmentService.getEquipments(
|
||||
page: anyNamed('page'),
|
||||
perPage: anyNamed('perPage'),
|
||||
status: anyNamed('status'),
|
||||
companyId: anyNamed('companyId'),
|
||||
warehouseLocationId: anyNamed('warehouseLocationId'),
|
||||
)).thenAnswer((_) async => []);
|
||||
|
||||
when(mockEquipmentService.deleteEquipment(any))
|
||||
.thenAnswer((_) async {});
|
||||
|
||||
controller = EquipmentListController(dataService: mockDataService);
|
||||
});
|
||||
|
||||
tearDown(() {
|
||||
controller.dispose();
|
||||
getIt.reset();
|
||||
});
|
||||
|
||||
group('EquipmentListController 단위 테스트', () {
|
||||
test('장비 선택/해제 테스트', () {
|
||||
// Arrange
|
||||
final equipment = MockDataHelpers.createMockUnifiedEquipment(id: 1);
|
||||
|
||||
// Act
|
||||
controller.selectEquipment(equipment.id, equipment.status, true);
|
||||
expect(controller.selectedEquipmentIds.contains('${equipment.id}:${equipment.status}'), true);
|
||||
|
||||
controller.selectEquipment(equipment.id, equipment.status, false);
|
||||
expect(controller.selectedEquipmentIds.contains('${equipment.id}:${equipment.status}'), false);
|
||||
});
|
||||
|
||||
test('전체 선택 테스트', () {
|
||||
// Arrange
|
||||
controller.equipments = MockDataHelpers.createMockUnifiedEquipmentList(count: 3);
|
||||
|
||||
// 수동으로 전체 선택
|
||||
for (final equipment in controller.equipments) {
|
||||
controller.selectEquipment(equipment.id, equipment.status, true);
|
||||
}
|
||||
|
||||
// Assert
|
||||
expect(controller.selectedEquipmentIds.length, 3);
|
||||
});
|
||||
|
||||
test('상태 필터 변경 테스트', () async {
|
||||
// Act
|
||||
await controller.changeStatusFilter('IN_STOCK');
|
||||
|
||||
// Assert
|
||||
expect(controller.selectedStatusFilter, 'IN_STOCK');
|
||||
});
|
||||
|
||||
test('장비 삭제 테스트', () async {
|
||||
// Arrange
|
||||
controller.equipments = MockDataHelpers.createMockUnifiedEquipmentList(count: 3);
|
||||
final equipmentToDelete = controller.equipments.first;
|
||||
|
||||
// Act
|
||||
final result = await controller.deleteEquipment(equipmentToDelete);
|
||||
|
||||
// Assert
|
||||
expect(result, true);
|
||||
expect(controller.equipments.length, 2);
|
||||
expect(controller.equipments.any((e) => e.id == equipmentToDelete.id), false);
|
||||
verify(mockEquipmentService.deleteEquipment(equipmentToDelete.equipment.id!)).called(1);
|
||||
});
|
||||
|
||||
test('선택된 장비 수 테스트', () {
|
||||
// Arrange
|
||||
controller.equipments = MockDataHelpers.createMockUnifiedEquipmentList(count: 5);
|
||||
|
||||
// 3개만 선택
|
||||
controller.selectEquipment(1, 'I', true);
|
||||
controller.selectEquipment(2, 'I', true);
|
||||
controller.selectEquipment(3, 'I', true);
|
||||
|
||||
// Assert
|
||||
expect(controller.getSelectedEquipmentCount(), 3);
|
||||
expect(controller.getSelectedInStockCount(), 3);
|
||||
});
|
||||
|
||||
test('에러 처리 테스트', () async {
|
||||
// Arrange
|
||||
when(mockEquipmentService.getEquipments(
|
||||
page: anyNamed('page'),
|
||||
perPage: anyNamed('perPage'),
|
||||
status: anyNamed('status'),
|
||||
companyId: anyNamed('companyId'),
|
||||
warehouseLocationId: anyNamed('warehouseLocationId'),
|
||||
)).thenThrow(Exception('장비 목록을 불러오는 중 오류가 발생했습니다.'));
|
||||
|
||||
// Act
|
||||
await controller.loadData();
|
||||
|
||||
// Assert
|
||||
expect(controller.error, isNotNull);
|
||||
expect(controller.isLoading, false);
|
||||
});
|
||||
});
|
||||
}
|
||||
255
test/unit/controllers/user_list_controller_test.dart
Normal file
255
test/unit/controllers/user_list_controller_test.dart
Normal file
@@ -0,0 +1,255 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:superport/screens/user/controllers/user_list_controller.dart';
|
||||
import 'package:superport/services/user_service.dart';
|
||||
import 'package:superport/models/company_model.dart';
|
||||
|
||||
import '../../helpers/test_helpers.dart';
|
||||
import '../../helpers/simple_mock_services.dart';
|
||||
import '../../helpers/simple_mock_services.mocks.dart';
|
||||
import '../../helpers/mock_data_helpers.dart';
|
||||
|
||||
void main() {
|
||||
late UserListController controller;
|
||||
late MockMockDataService mockDataService;
|
||||
late MockUserService mockUserService;
|
||||
late GetIt getIt;
|
||||
|
||||
setUp(() {
|
||||
getIt = setupTestGetIt();
|
||||
mockDataService = MockMockDataService();
|
||||
mockUserService = MockUserService();
|
||||
|
||||
// GetIt에 UserService 등록
|
||||
getIt.registerSingleton<UserService>(mockUserService);
|
||||
|
||||
// Mock 설정
|
||||
SimpleMockServiceHelpers.setupMockDataServiceMock(mockDataService);
|
||||
SimpleMockServiceHelpers.setupUserServiceMock(mockUserService);
|
||||
|
||||
controller = UserListController(dataService: mockDataService);
|
||||
});
|
||||
|
||||
tearDown(() {
|
||||
controller.dispose();
|
||||
getIt.reset();
|
||||
});
|
||||
|
||||
group('UserListController 단위 테스트', () {
|
||||
test('초기 상태 확인', () {
|
||||
expect(controller.users, isEmpty);
|
||||
expect(controller.isLoading, false);
|
||||
expect(controller.error, isNull);
|
||||
expect(controller.hasMoreData, true);
|
||||
expect(controller.searchQuery, '');
|
||||
expect(controller.filterCompanyId, isNull);
|
||||
expect(controller.filterRole, isNull);
|
||||
expect(controller.filterIsActive, isNull);
|
||||
});
|
||||
|
||||
test('사용자 목록 로드 테스트', () async {
|
||||
// Act
|
||||
await controller.loadUsers();
|
||||
|
||||
// Assert
|
||||
expect(controller.users, isNotEmpty);
|
||||
expect(controller.users.length, 10);
|
||||
expect(controller.isLoading, false);
|
||||
expect(controller.error, isNull);
|
||||
verify(mockUserService.getUsers(
|
||||
page: 1,
|
||||
perPage: 20,
|
||||
isActive: null,
|
||||
companyId: null,
|
||||
role: null,
|
||||
)).called(1);
|
||||
});
|
||||
|
||||
test('검색 쿼리 설정 및 검색 테스트', () async {
|
||||
// Act
|
||||
controller.setSearchQuery('사용자 1');
|
||||
|
||||
// Assert
|
||||
expect(controller.searchQuery, '사용자 1');
|
||||
await Future.delayed(Duration(milliseconds: 100)); // loadUsers 완료 대기
|
||||
verify(mockUserService.getUsers(
|
||||
page: 1,
|
||||
perPage: 20,
|
||||
isActive: null,
|
||||
companyId: null,
|
||||
role: null,
|
||||
)).called(1);
|
||||
});
|
||||
|
||||
test('필터 설정 테스트', () async {
|
||||
// Act
|
||||
controller.setFilters(
|
||||
companyId: 1,
|
||||
role: 'S',
|
||||
isActive: true,
|
||||
);
|
||||
|
||||
// Assert
|
||||
expect(controller.filterCompanyId, 1);
|
||||
expect(controller.filterRole, 'S');
|
||||
expect(controller.filterIsActive, true);
|
||||
await Future.delayed(Duration(milliseconds: 100)); // loadUsers 완료 대기
|
||||
verify(mockUserService.getUsers(
|
||||
page: 1,
|
||||
perPage: 20,
|
||||
isActive: true,
|
||||
companyId: 1,
|
||||
role: 'S',
|
||||
)).called(1);
|
||||
});
|
||||
|
||||
test('필터 초기화 테스트', () async {
|
||||
// Arrange
|
||||
controller.setFilters(
|
||||
companyId: 1,
|
||||
role: 'S',
|
||||
isActive: true,
|
||||
);
|
||||
await Future.delayed(Duration(milliseconds: 100));
|
||||
|
||||
// Act
|
||||
controller.clearFilters();
|
||||
|
||||
// Assert
|
||||
expect(controller.filterCompanyId, isNull);
|
||||
expect(controller.filterRole, isNull);
|
||||
expect(controller.filterIsActive, isNull);
|
||||
expect(controller.searchQuery, '');
|
||||
});
|
||||
|
||||
test('사용자 삭제 테스트', () async {
|
||||
// Arrange
|
||||
await controller.loadUsers();
|
||||
final initialUserCount = controller.users.length;
|
||||
bool deletedCallbackCalled = false;
|
||||
|
||||
// Act
|
||||
await controller.deleteUser(
|
||||
1,
|
||||
() => deletedCallbackCalled = true,
|
||||
(error) => fail('삭제 실패: $error'),
|
||||
);
|
||||
|
||||
// Assert
|
||||
expect(deletedCallbackCalled, true);
|
||||
expect(controller.users.length, initialUserCount - 1);
|
||||
expect(controller.users.any((u) => u.id == 1), false);
|
||||
verify(mockUserService.deleteUser(1)).called(1);
|
||||
});
|
||||
|
||||
test('사용자 상태 변경 테스트', () async {
|
||||
// Arrange
|
||||
await controller.loadUsers();
|
||||
|
||||
// Act
|
||||
await controller.changeUserStatus(
|
||||
1,
|
||||
false,
|
||||
(error) => fail('상태 변경 실패: $error'),
|
||||
);
|
||||
|
||||
// Assert
|
||||
final updatedUser = controller.users.firstWhere((u) => u.id == 1);
|
||||
expect(updatedUser.isActive, false);
|
||||
verify(mockUserService.changeUserStatus(1, false)).called(1);
|
||||
});
|
||||
|
||||
test('에러 처리 테스트', () async {
|
||||
// Arrange
|
||||
SimpleMockServiceHelpers.setupUserServiceMock(
|
||||
mockUserService,
|
||||
getUsersSuccess: false,
|
||||
);
|
||||
|
||||
// Act
|
||||
await controller.loadUsers();
|
||||
|
||||
// Assert
|
||||
expect(controller.error, isNotNull);
|
||||
expect(controller.isLoading, false);
|
||||
expect(controller.users, isEmpty);
|
||||
});
|
||||
|
||||
test('페이지네이션 - 더 불러오기 테스트', () async {
|
||||
// Arrange
|
||||
// 첫 번째 페이지와 두 번째 페이지에 대해 다른 응답 설정
|
||||
when(mockUserService.getUsers(
|
||||
page: 1,
|
||||
perPage: 20,
|
||||
isActive: anyNamed('isActive'),
|
||||
companyId: anyNamed('companyId'),
|
||||
role: anyNamed('role'),
|
||||
)).thenAnswer((_) async =>
|
||||
MockDataHelpers.createMockUserModelList(count: 20),
|
||||
);
|
||||
|
||||
when(mockUserService.getUsers(
|
||||
page: 2,
|
||||
perPage: 20,
|
||||
isActive: anyNamed('isActive'),
|
||||
companyId: anyNamed('companyId'),
|
||||
role: anyNamed('role'),
|
||||
)).thenAnswer((_) async =>
|
||||
MockDataHelpers.createMockUserModelList(count: 10),
|
||||
);
|
||||
|
||||
await controller.loadUsers();
|
||||
final initialCount = controller.users.length;
|
||||
|
||||
// Act
|
||||
await controller.loadMore();
|
||||
|
||||
// Assert
|
||||
expect(controller.users.length, greaterThan(initialCount));
|
||||
verify(mockUserService.getUsers(
|
||||
page: 2,
|
||||
perPage: 20,
|
||||
isActive: null,
|
||||
companyId: null,
|
||||
role: null,
|
||||
)).called(1);
|
||||
});
|
||||
|
||||
test('Mock 모드에서 필터링 테스트', () async {
|
||||
// Arrange
|
||||
controller.toggleApiMode(); // Mock 모드로 전환
|
||||
|
||||
// Act
|
||||
controller.setFilters(companyId: 1, role: 'S');
|
||||
await Future.delayed(Duration(milliseconds: 100));
|
||||
|
||||
// Assert
|
||||
// Mock 모드에서는 getAllUsers를 통해 전체 데이터를 가져온 후 필터링
|
||||
verify(mockDataService.getAllUsers()).called(greaterThanOrEqualTo(1));
|
||||
});
|
||||
|
||||
test('지점명 조회 테스트', () {
|
||||
// Arrange
|
||||
final mockCompany = Company(
|
||||
id: 1,
|
||||
name: '테스트 회사',
|
||||
branches: [
|
||||
Branch(
|
||||
id: 1,
|
||||
companyId: 1,
|
||||
name: '본사',
|
||||
),
|
||||
],
|
||||
);
|
||||
when(mockDataService.getCompanyById(1)).thenReturn(mockCompany);
|
||||
|
||||
// Act
|
||||
final branchName = controller.getBranchName(1, 1);
|
||||
|
||||
// Assert
|
||||
expect(branchName, '본사');
|
||||
verify(mockDataService.getCompanyById(1)).called(1);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user