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:
525
test/helpers/mock_services.dart
Normal file
525
test/helpers/mock_services.dart
Normal file
@@ -0,0 +1,525 @@
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:superport/services/auth_service.dart';
|
||||
import 'package:superport/services/company_service.dart';
|
||||
import 'package:superport/services/equipment_service.dart';
|
||||
import 'package:superport/services/user_service.dart';
|
||||
import 'package:superport/services/license_service.dart';
|
||||
import 'package:superport/services/warehouse_service.dart';
|
||||
import 'package:superport/services/dashboard_service.dart';
|
||||
import 'package:superport/services/mock_data_service.dart';
|
||||
import 'package:superport/core/errors/failures.dart';
|
||||
|
||||
import 'mock_data_helpers.dart';
|
||||
import 'mock_services.mocks.dart';
|
||||
|
||||
// Mockito 어노테이션으로 Mock 클래스 생성
|
||||
@GenerateMocks([
|
||||
AuthService,
|
||||
CompanyService,
|
||||
EquipmentService,
|
||||
UserService,
|
||||
LicenseService,
|
||||
WarehouseService,
|
||||
DashboardService,
|
||||
MockDataService,
|
||||
])
|
||||
void main() {}
|
||||
|
||||
/// Mock 서비스 설정 헬퍼
|
||||
class MockServiceHelpers {
|
||||
/// AuthService Mock 설정
|
||||
static void setupAuthServiceMock(
|
||||
MockAuthService mockAuthService, {
|
||||
bool isLoggedIn = false,
|
||||
bool loginSuccess = true,
|
||||
bool logoutSuccess = true,
|
||||
}) {
|
||||
// isLoggedIn
|
||||
when(mockAuthService.isLoggedIn())
|
||||
.thenAnswer((_) async => isLoggedIn);
|
||||
|
||||
// login
|
||||
if (loginSuccess) {
|
||||
when(mockAuthService.login(any))
|
||||
.thenAnswer((_) async => Right(MockDataHelpers.createMockLoginResponse()));
|
||||
} else {
|
||||
when(mockAuthService.login(any))
|
||||
.thenAnswer((_) async => Left(AuthenticationFailure(
|
||||
message: '이메일 또는 비밀번호가 올바르지 않습니다.',
|
||||
)));
|
||||
}
|
||||
|
||||
// logout
|
||||
if (logoutSuccess) {
|
||||
when(mockAuthService.logout())
|
||||
.thenAnswer((_) async => const Right(null));
|
||||
} else {
|
||||
when(mockAuthService.logout())
|
||||
.thenAnswer((_) async => Left(ServerFailure(
|
||||
message: '로그아웃 중 오류가 발생했습니다.',
|
||||
)));
|
||||
}
|
||||
|
||||
// getCurrentUser
|
||||
when(mockAuthService.getCurrentUser())
|
||||
.thenAnswer((_) async => isLoggedIn ? MockDataHelpers.createMockUser() : null);
|
||||
|
||||
// getAccessToken
|
||||
when(mockAuthService.getAccessToken())
|
||||
.thenAnswer((_) async => isLoggedIn ? 'test_access_token' : null);
|
||||
|
||||
// authStateChanges
|
||||
when(mockAuthService.authStateChanges)
|
||||
.thenAnswer((_) => Stream.value(isLoggedIn));
|
||||
}
|
||||
|
||||
/// CompanyService Mock 설정
|
||||
static void setupCompanyServiceMock(
|
||||
MockCompanyService mockCompanyService, {
|
||||
bool getCompaniesSuccess = true,
|
||||
bool createCompanySuccess = true,
|
||||
bool updateCompanySuccess = true,
|
||||
bool deleteCompanySuccess = true,
|
||||
int companyCount = 10,
|
||||
}) {
|
||||
// getCompanies
|
||||
if (getCompaniesSuccess) {
|
||||
when(mockCompanyService.getCompanies(
|
||||
page: anyNamed('page'),
|
||||
perPage: anyNamed('perPage'),
|
||||
search: anyNamed('search'),
|
||||
isActive: anyNamed('isActive'),
|
||||
)).thenAnswer((_) async =>
|
||||
MockDataHelpers.createMockCompanyList(count: companyCount),
|
||||
);
|
||||
} else {
|
||||
when(mockCompanyService.getCompanies(
|
||||
page: anyNamed('page'),
|
||||
perPage: anyNamed('perPage'),
|
||||
search: anyNamed('search'),
|
||||
isActive: anyNamed('isActive'),
|
||||
)).thenThrow(
|
||||
ServerFailure(message: '회사 목록을 불러오는 중 오류가 발생했습니다.'),
|
||||
);
|
||||
}
|
||||
|
||||
// createCompany
|
||||
if (createCompanySuccess) {
|
||||
when(mockCompanyService.createCompany(any))
|
||||
.thenAnswer((_) async => MockDataHelpers.createMockCompany());
|
||||
} else {
|
||||
when(mockCompanyService.createCompany(any))
|
||||
.thenThrow(ServerFailure(
|
||||
message: '회사 등록 중 오류가 발생했습니다.',
|
||||
));
|
||||
}
|
||||
|
||||
// updateCompany
|
||||
if (updateCompanySuccess) {
|
||||
when(mockCompanyService.updateCompany(any, any))
|
||||
.thenAnswer((_) async => MockDataHelpers.createMockCompany());
|
||||
} else {
|
||||
when(mockCompanyService.updateCompany(any, any))
|
||||
.thenThrow(ServerFailure(
|
||||
message: '회사 정보 수정 중 오류가 발생했습니다.',
|
||||
));
|
||||
}
|
||||
|
||||
// deleteCompany
|
||||
if (deleteCompanySuccess) {
|
||||
when(mockCompanyService.deleteCompany(any))
|
||||
.thenAnswer((_) async {});
|
||||
} else {
|
||||
when(mockCompanyService.deleteCompany(any))
|
||||
.thenThrow(ServerFailure(
|
||||
message: '회사 삭제 중 오류가 발생했습니다.',
|
||||
));
|
||||
}
|
||||
|
||||
// getCompanyDetail
|
||||
when(mockCompanyService.getCompanyDetail(any))
|
||||
.thenAnswer((_) async => MockDataHelpers.createMockCompany());
|
||||
|
||||
// checkDuplicateCompany
|
||||
when(mockCompanyService.checkDuplicateCompany(any))
|
||||
.thenAnswer((_) async => false);
|
||||
|
||||
// getCompanyNames
|
||||
when(mockCompanyService.getCompanyNames())
|
||||
.thenAnswer((_) async => [{'id': 1, 'name': '테스트 회사 1'}, {'id': 2, 'name': '테스트 회사 2'}, {'id': 3, 'name': '테스트 회사 3'}]);
|
||||
}
|
||||
|
||||
/// EquipmentService Mock 설정
|
||||
static void setupEquipmentServiceMock(
|
||||
MockEquipmentService mockEquipmentService, {
|
||||
bool getEquipmentsSuccess = true,
|
||||
bool createEquipmentSuccess = true,
|
||||
bool equipmentInSuccess = true,
|
||||
bool equipmentOutSuccess = true,
|
||||
int equipmentCount = 10,
|
||||
}) {
|
||||
// getEquipments
|
||||
if (getEquipmentsSuccess) {
|
||||
when(mockEquipmentService.getEquipments(
|
||||
page: anyNamed('page'),
|
||||
perPage: anyNamed('perPage'),
|
||||
status: anyNamed('status'),
|
||||
companyId: anyNamed('companyId'),
|
||||
warehouseLocationId: anyNamed('warehouseLocationId'),
|
||||
)).thenAnswer((_) async =>
|
||||
MockDataHelpers.createMockEquipmentModelList(count: equipmentCount),
|
||||
);
|
||||
} else {
|
||||
when(mockEquipmentService.getEquipments(
|
||||
page: anyNamed('page'),
|
||||
perPage: anyNamed('perPage'),
|
||||
status: anyNamed('status'),
|
||||
companyId: anyNamed('companyId'),
|
||||
warehouseLocationId: anyNamed('warehouseLocationId'),
|
||||
)).thenThrow(ServerFailure(
|
||||
message: '장비 목록을 불러오는 중 오류가 발생했습니다.',
|
||||
));
|
||||
}
|
||||
|
||||
// createEquipment
|
||||
if (createEquipmentSuccess) {
|
||||
when(mockEquipmentService.createEquipment(any))
|
||||
.thenAnswer((_) async => MockDataHelpers.createMockEquipmentModel());
|
||||
} else {
|
||||
when(mockEquipmentService.createEquipment(any))
|
||||
.thenThrow(ServerFailure(
|
||||
message: '장비 등록 중 오류가 발생했습니다.',
|
||||
));
|
||||
}
|
||||
|
||||
// equipmentIn
|
||||
if (equipmentInSuccess) {
|
||||
when(mockEquipmentService.equipmentIn(
|
||||
equipmentId: anyNamed('equipmentId'),
|
||||
quantity: anyNamed('quantity'),
|
||||
warehouseLocationId: anyNamed('warehouseLocationId'),
|
||||
notes: anyNamed('notes'),
|
||||
)).thenAnswer((_) async => MockDataHelpers.createMockEquipmentIoResponse());
|
||||
} else {
|
||||
when(mockEquipmentService.equipmentIn(
|
||||
equipmentId: anyNamed('equipmentId'),
|
||||
quantity: anyNamed('quantity'),
|
||||
warehouseLocationId: anyNamed('warehouseLocationId'),
|
||||
notes: anyNamed('notes'),
|
||||
)).thenThrow(ServerFailure(
|
||||
message: '장비 입고 처리 중 오류가 발생했습니다.',
|
||||
));
|
||||
}
|
||||
|
||||
// equipmentOut
|
||||
if (equipmentOutSuccess) {
|
||||
when(mockEquipmentService.equipmentOut(
|
||||
equipmentId: anyNamed('equipmentId'),
|
||||
quantity: anyNamed('quantity'),
|
||||
companyId: anyNamed('companyId'),
|
||||
branchId: anyNamed('branchId'),
|
||||
notes: anyNamed('notes'),
|
||||
)).thenAnswer((_) async => MockDataHelpers.createMockEquipmentIoResponse());
|
||||
} else {
|
||||
when(mockEquipmentService.equipmentOut(
|
||||
equipmentId: anyNamed('equipmentId'),
|
||||
quantity: anyNamed('quantity'),
|
||||
companyId: anyNamed('companyId'),
|
||||
branchId: anyNamed('branchId'),
|
||||
notes: anyNamed('notes'),
|
||||
)).thenThrow(ServerFailure(
|
||||
message: '장비 출고 처리 중 오류가 발생했습니다.',
|
||||
));
|
||||
}
|
||||
|
||||
// getEquipmentDetail
|
||||
when(mockEquipmentService.getEquipmentDetail(any))
|
||||
.thenAnswer((_) async => MockDataHelpers.createMockEquipmentModel());
|
||||
|
||||
// getEquipment (alias for getEquipmentDetail)
|
||||
when(mockEquipmentService.getEquipment(any))
|
||||
.thenAnswer((_) async => MockDataHelpers.createMockEquipmentModel());
|
||||
|
||||
// getEquipmentHistory
|
||||
when(mockEquipmentService.getEquipmentHistory(any, page: anyNamed('page'), perPage: anyNamed('perPage')))
|
||||
.thenAnswer((_) async => []);
|
||||
|
||||
// Additional mock setups can be added here if needed
|
||||
}
|
||||
|
||||
/// UserService Mock 설정
|
||||
static void setupUserServiceMock(
|
||||
MockUserService mockUserService, {
|
||||
bool getUsersSuccess = true,
|
||||
bool createUserSuccess = true,
|
||||
bool updateUserSuccess = true,
|
||||
bool deleteUserSuccess = true,
|
||||
int userCount = 10,
|
||||
}) {
|
||||
// getUsers
|
||||
if (getUsersSuccess) {
|
||||
when(mockUserService.getUsers(
|
||||
page: anyNamed('page'),
|
||||
perPage: anyNamed('perPage'),
|
||||
isActive: anyNamed('isActive'),
|
||||
companyId: anyNamed('companyId'),
|
||||
role: anyNamed('role'),
|
||||
)).thenAnswer((_) async =>
|
||||
MockDataHelpers.createMockUserModelList(count: userCount),
|
||||
);
|
||||
} else {
|
||||
when(mockUserService.getUsers(
|
||||
page: anyNamed('page'),
|
||||
perPage: anyNamed('perPage'),
|
||||
isActive: anyNamed('isActive'),
|
||||
companyId: anyNamed('companyId'),
|
||||
role: anyNamed('role'),
|
||||
)).thenThrow(Exception('사용자 목록 조회 실패'));
|
||||
}
|
||||
|
||||
// createUser
|
||||
if (createUserSuccess) {
|
||||
when(mockUserService.createUser(
|
||||
username: anyNamed('username'),
|
||||
email: anyNamed('email'),
|
||||
password: anyNamed('password'),
|
||||
name: anyNamed('name'),
|
||||
role: anyNamed('role'),
|
||||
companyId: anyNamed('companyId'),
|
||||
branchId: anyNamed('branchId'),
|
||||
phone: anyNamed('phone'),
|
||||
position: anyNamed('position'),
|
||||
)).thenAnswer((_) async => MockDataHelpers.createMockUserModel());
|
||||
} else {
|
||||
when(mockUserService.createUser(
|
||||
username: anyNamed('username'),
|
||||
email: anyNamed('email'),
|
||||
password: anyNamed('password'),
|
||||
name: anyNamed('name'),
|
||||
role: anyNamed('role'),
|
||||
companyId: anyNamed('companyId'),
|
||||
branchId: anyNamed('branchId'),
|
||||
phone: anyNamed('phone'),
|
||||
position: anyNamed('position'),
|
||||
)).thenThrow(Exception('사용자 생성 실패'));
|
||||
}
|
||||
|
||||
// updateUser
|
||||
if (updateUserSuccess) {
|
||||
when(mockUserService.updateUser(
|
||||
any,
|
||||
name: anyNamed('name'),
|
||||
email: anyNamed('email'),
|
||||
password: anyNamed('password'),
|
||||
phone: anyNamed('phone'),
|
||||
companyId: anyNamed('companyId'),
|
||||
branchId: anyNamed('branchId'),
|
||||
role: anyNamed('role'),
|
||||
position: anyNamed('position'),
|
||||
)).thenAnswer((_) async => MockDataHelpers.createMockUserModel());
|
||||
} else {
|
||||
when(mockUserService.updateUser(
|
||||
any,
|
||||
name: anyNamed('name'),
|
||||
email: anyNamed('email'),
|
||||
password: anyNamed('password'),
|
||||
phone: anyNamed('phone'),
|
||||
companyId: anyNamed('companyId'),
|
||||
branchId: anyNamed('branchId'),
|
||||
role: anyNamed('role'),
|
||||
position: anyNamed('position'),
|
||||
)).thenThrow(Exception('사용자 수정 실패'));
|
||||
}
|
||||
|
||||
// deleteUser
|
||||
if (deleteUserSuccess) {
|
||||
when(mockUserService.deleteUser(any))
|
||||
.thenAnswer((_) async {});
|
||||
} else {
|
||||
when(mockUserService.deleteUser(any))
|
||||
.thenThrow(Exception('사용자 삭제 실패'));
|
||||
}
|
||||
|
||||
// getUser
|
||||
when(mockUserService.getUser(any))
|
||||
.thenAnswer((_) async => MockDataHelpers.createMockUserModel());
|
||||
|
||||
// changePassword
|
||||
when(mockUserService.changePassword(any, any, any))
|
||||
.thenAnswer((_) async {});
|
||||
|
||||
// changeUserStatus
|
||||
when(mockUserService.changeUserStatus(any, any))
|
||||
.thenAnswer((_) async => MockDataHelpers.createMockUserModel());
|
||||
|
||||
// checkDuplicateUsername
|
||||
when(mockUserService.checkDuplicateUsername(any))
|
||||
.thenAnswer((_) async => false);
|
||||
}
|
||||
|
||||
/// LicenseService Mock 설정
|
||||
static void setupLicenseServiceMock(
|
||||
MockLicenseService mockLicenseService, {
|
||||
bool getLicensesSuccess = true,
|
||||
bool createLicenseSuccess = true,
|
||||
bool updateLicenseSuccess = true,
|
||||
bool deleteLicenseSuccess = true,
|
||||
int licenseCount = 10,
|
||||
}) {
|
||||
// getLicenses
|
||||
if (getLicensesSuccess) {
|
||||
when(mockLicenseService.getLicenses(
|
||||
page: anyNamed('page'),
|
||||
perPage: anyNamed('perPage'),
|
||||
isActive: anyNamed('isActive'),
|
||||
companyId: anyNamed('companyId'),
|
||||
assignedUserId: anyNamed('assignedUserId'),
|
||||
licenseType: anyNamed('licenseType'),
|
||||
)).thenAnswer((_) async =>
|
||||
MockDataHelpers.createMockLicenseModelList(count: licenseCount),
|
||||
);
|
||||
} else {
|
||||
when(mockLicenseService.getLicenses(
|
||||
page: anyNamed('page'),
|
||||
perPage: anyNamed('perPage'),
|
||||
isActive: anyNamed('isActive'),
|
||||
companyId: anyNamed('companyId'),
|
||||
assignedUserId: anyNamed('assignedUserId'),
|
||||
licenseType: anyNamed('licenseType'),
|
||||
)).thenThrow(ServerFailure(
|
||||
message: '라이선스 목록을 불러오는 데 실패했습니다',
|
||||
));
|
||||
}
|
||||
|
||||
// createLicense
|
||||
if (createLicenseSuccess) {
|
||||
when(mockLicenseService.createLicense(any))
|
||||
.thenAnswer((_) async => MockDataHelpers.createMockLicenseModel());
|
||||
} else {
|
||||
when(mockLicenseService.createLicense(any))
|
||||
.thenThrow(ServerFailure(
|
||||
message: '라이선스 생성에 실패했습니다',
|
||||
));
|
||||
}
|
||||
|
||||
// updateLicense
|
||||
if (updateLicenseSuccess) {
|
||||
when(mockLicenseService.updateLicense(any))
|
||||
.thenAnswer((_) async => MockDataHelpers.createMockLicenseModel());
|
||||
} else {
|
||||
when(mockLicenseService.updateLicense(any))
|
||||
.thenThrow(ServerFailure(
|
||||
message: '라이선스 수정에 실패했습니다',
|
||||
));
|
||||
}
|
||||
|
||||
// deleteLicense
|
||||
if (deleteLicenseSuccess) {
|
||||
when(mockLicenseService.deleteLicense(any))
|
||||
.thenAnswer((_) async {});
|
||||
} else {
|
||||
when(mockLicenseService.deleteLicense(any))
|
||||
.thenThrow(ServerFailure(
|
||||
message: '라이선스 삭제에 실패했습니다',
|
||||
));
|
||||
}
|
||||
|
||||
// getLicenseById
|
||||
when(mockLicenseService.getLicenseById(any))
|
||||
.thenAnswer((_) async => MockDataHelpers.createMockLicenseModel());
|
||||
|
||||
// getExpiringLicenses
|
||||
when(mockLicenseService.getExpiringLicenses(
|
||||
days: anyNamed('days'),
|
||||
page: anyNamed('page'),
|
||||
perPage: anyNamed('perPage'),
|
||||
)).thenAnswer((_) async => MockDataHelpers.createMockLicenseModelList(count: 3));
|
||||
|
||||
// assignLicense
|
||||
when(mockLicenseService.assignLicense(any, any))
|
||||
.thenAnswer((_) async => MockDataHelpers.createMockLicenseModel());
|
||||
|
||||
// unassignLicense
|
||||
when(mockLicenseService.unassignLicense(any))
|
||||
.thenAnswer((_) async => MockDataHelpers.createMockLicenseModel());
|
||||
}
|
||||
|
||||
/// WarehouseService Mock 설정
|
||||
static void setupWarehouseServiceMock(
|
||||
MockWarehouseService mockWarehouseService, {
|
||||
bool getWarehousesSuccess = true,
|
||||
bool createWarehouseSuccess = true,
|
||||
bool updateWarehouseSuccess = true,
|
||||
bool deleteWarehouseSuccess = true,
|
||||
int warehouseCount = 5,
|
||||
}) {
|
||||
// getWarehouses
|
||||
if (getWarehousesSuccess) {
|
||||
when(mockWarehouseService.getWarehouseLocations(
|
||||
page: anyNamed('page'),
|
||||
perPage: anyNamed('perPage'),
|
||||
isActive: anyNamed('isActive'),
|
||||
)).thenAnswer((_) async =>
|
||||
MockDataHelpers.createMockWarehouseLocationList(count: warehouseCount),
|
||||
);
|
||||
} else {
|
||||
when(mockWarehouseService.getWarehouseLocations(
|
||||
page: anyNamed('page'),
|
||||
perPage: anyNamed('perPage'),
|
||||
isActive: anyNamed('isActive'),
|
||||
)).thenThrow(ServerFailure(
|
||||
message: '창고 위치 목록을 불러오는 데 실패했습니다',
|
||||
));
|
||||
}
|
||||
|
||||
// createWarehouse
|
||||
if (createWarehouseSuccess) {
|
||||
when(mockWarehouseService.createWarehouseLocation(any))
|
||||
.thenAnswer((_) async => MockDataHelpers.createMockWarehouseLocation());
|
||||
} else {
|
||||
when(mockWarehouseService.createWarehouseLocation(any))
|
||||
.thenThrow(ServerFailure(
|
||||
message: '창고 위치 생성에 실패했습니다',
|
||||
));
|
||||
}
|
||||
|
||||
// updateWarehouse
|
||||
if (updateWarehouseSuccess) {
|
||||
when(mockWarehouseService.updateWarehouseLocation(any))
|
||||
.thenAnswer((_) async => MockDataHelpers.createMockWarehouseLocation());
|
||||
} else {
|
||||
when(mockWarehouseService.updateWarehouseLocation(any))
|
||||
.thenThrow(ServerFailure(
|
||||
message: '창고 위치 수정에 실패했습니다',
|
||||
));
|
||||
}
|
||||
|
||||
// deleteWarehouse
|
||||
if (deleteWarehouseSuccess) {
|
||||
when(mockWarehouseService.deleteWarehouseLocation(any))
|
||||
.thenAnswer((_) async {});
|
||||
} else {
|
||||
when(mockWarehouseService.deleteWarehouseLocation(any))
|
||||
.thenThrow(ServerFailure(
|
||||
message: '창고 위치 삭제에 실패했습니다',
|
||||
));
|
||||
}
|
||||
|
||||
// getWarehouseLocationById
|
||||
when(mockWarehouseService.getWarehouseLocationById(any))
|
||||
.thenAnswer((_) async => MockDataHelpers.createMockWarehouseLocation());
|
||||
|
||||
// getWarehouseEquipment
|
||||
when(mockWarehouseService.getWarehouseEquipment(
|
||||
any,
|
||||
page: anyNamed('page'),
|
||||
perPage: anyNamed('perPage'),
|
||||
)).thenAnswer((_) async => []);
|
||||
|
||||
// getWarehouseCapacity
|
||||
when(mockWarehouseService.getWarehouseCapacity(any))
|
||||
.thenAnswer((_) async => MockDataHelpers.createMockWarehouseCapacityInfo());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user