Skip to content

Commit

Permalink
Merge pull request #326 from wakamenod/325-mobile-test-トランザクション削除-テスト追加
Browse files Browse the repository at this point in the history
[Mobile] [Test] トランザクション削除 テスト追加 #325
  • Loading branch information
wakamenod authored Jul 20, 2023
2 parents 7abe5ca + df21b15 commit 9e6e383
Show file tree
Hide file tree
Showing 8 changed files with 267 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,5 @@ class DeleteExpenseScheduleController
// dioのバージョンを上げれば直るかもしれないがopenapi側の制約で上げられない
ref.invalidate(fetchSchedulesProvider);
});

// TODO エラーハンドリング
// if (!state.hasError) {
// ref.read(itemQuantityControllerProvider.notifier).updateQuantity(1);
// }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,5 @@ class DeleteIncomeScheduleController extends _$DeleteIncomeScheduleController {
// dioのバージョンを上げれば直るかもしれないがopenapi側の制約で上げられない
ref.invalidate(fetchSchedulesProvider);
});

// TODO エラーハンドリング
// if (!state.hasError) {
// ref.read(itemQuantityControllerProvider.notifier).updateQuantity(1);
// }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class ExpenseDetailRepository {
final api = _openapi.getSuitoExpenseApi();
final response =
await api.expenseDetail(request: ExpenseDetailReq((r) => r.id = id));
return response.data ?? ExpenseDetailRes();
return response.data!;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,5 @@ class DeleteExpenseController extends _$DeleteExpenseController {
// dioのバージョンを上げれば直るかもしれないがopenapi側の制約で上げられない
ref.invalidate(fetchTransactionsProvider);
});

// TODO エラーハンドリング
// if (!state.hasError) {
// ref.read(itemQuantityControllerProvider.notifier).updateQuantity(1);
// }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
import 'package:suito/src/features/schedules/repositories/expense/delete_expense_schedule_repository.dart';
import 'package:suito/src/features/schedules/services/expense/delete_expense_schedule_controller.dart';

import '../../../../mocks.dart';

void main() {
ProviderContainer makeProviderContainer(
MockDeleteExpenseScheduleRepository repo) {
final container = ProviderContainer(
overrides: [
deleteExpenseScheduleRepositoryProvider.overrideWithValue(repo),
],
);
addTearDown(container.dispose);
return container;
}

setUpAll(() {
registerFallbackValue(const AsyncLoading<int>());
});

group('deleteExpenseScheduleController', () {
test('delete expense schedule, success', () async {
// setup
const scheduleID = 'test_expense_schedule_id';
final deleteRepo = MockDeleteExpenseScheduleRepository();
when(() => deleteRepo.deleteExpenseSchedule(scheduleID)).thenAnswer(
(_) => Future.value(null),
);
final container = makeProviderContainer(deleteRepo);
final controller =
container.read(deleteExpenseScheduleControllerProvider.notifier);
final listener = Listener<AsyncValue<void>>();
container.listen(
deleteExpenseScheduleControllerProvider,
listener,
fireImmediately: true,
);
const data = AsyncData<void>(null);
verify(() => listener(null, data));
// run
await controller.deleteExpenseSchedule(scheduleID);
// verify
verifyInOrder([
() => listener(data, any(that: isA<AsyncLoading>())),
() => listener(any(that: isA<AsyncLoading>()), data),
]);
verifyNoMoreInteractions(listener);
verify(() => deleteRepo.deleteExpenseSchedule(scheduleID)).called(1);
});

test('delete expense schedule, failure', () async {
// setup
const scheduleID = 'test_expense_schedule_id';
final deleteRepo = MockDeleteExpenseScheduleRepository();
when(() => deleteRepo.deleteExpenseSchedule(scheduleID)).thenThrow(
(_) => Exception('Connection failed'),
);
final container = makeProviderContainer(deleteRepo);
final controller =
container.read(deleteExpenseScheduleControllerProvider.notifier);
final listener = Listener<AsyncValue<void>>();
container.listen(
deleteExpenseScheduleControllerProvider,
listener,
fireImmediately: true,
);
const data = AsyncData<void>(null);
verify(() => listener(null, data));
// run
await controller.deleteExpenseSchedule(scheduleID);
// verify
verifyInOrder([
() => listener(data, any(that: isA<AsyncLoading>())),
() => listener(
any(that: isA<AsyncLoading>()), any(that: isA<AsyncError>())),
]);
verifyNoMoreInteractions(listener);
verify(() => deleteRepo.deleteExpenseSchedule(scheduleID)).called(1);
});
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
import 'package:suito/src/features/schedules/repositories/income/delete_income_schedule_repository.dart';
import 'package:suito/src/features/schedules/services/income/delete_income_schedule_controller.dart';

import '../../../../mocks.dart';

void main() {
ProviderContainer makeProviderContainer(
MockDeleteIncomeScheduleRepository repo) {
final container = ProviderContainer(
overrides: [
deleteIncomeScheduleRepositoryProvider.overrideWithValue(repo),
],
);
addTearDown(container.dispose);
return container;
}

setUpAll(() {
registerFallbackValue(const AsyncLoading<int>());
});

group('deleteIncomeScheduleController', () {
test('delete income schedule, success', () async {
// setup
const scheduleID = 'test_income_schedule_id';
final deleteRepo = MockDeleteIncomeScheduleRepository();
when(() => deleteRepo.deleteIncomeSchedule(scheduleID)).thenAnswer(
(_) => Future.value(null),
);
final container = makeProviderContainer(deleteRepo);
final controller =
container.read(deleteIncomeScheduleControllerProvider.notifier);
final listener = Listener<AsyncValue<void>>();
container.listen(
deleteIncomeScheduleControllerProvider,
listener,
fireImmediately: true,
);
const data = AsyncData<void>(null);
verify(() => listener(null, data));
// run
await controller.deleteIncomeSchedule(scheduleID);
// verify
verifyInOrder([
() => listener(data, any(that: isA<AsyncLoading>())),
() => listener(any(that: isA<AsyncLoading>()), data),
]);
verifyNoMoreInteractions(listener);
verify(() => deleteRepo.deleteIncomeSchedule(scheduleID)).called(1);
});

test('delete income schedule, failure', () async {
// setup
const scheduleID = 'test_income_schedule_id';
final deleteRepo = MockDeleteIncomeScheduleRepository();
when(() => deleteRepo.deleteIncomeSchedule(scheduleID)).thenThrow(
(_) => Exception('Connection failed'),
);
final container = makeProviderContainer(deleteRepo);
final controller =
container.read(deleteIncomeScheduleControllerProvider.notifier);
final listener = Listener<AsyncValue<void>>();
container.listen(
deleteIncomeScheduleControllerProvider,
listener,
fireImmediately: true,
);
const data = AsyncData<void>(null);
verify(() => listener(null, data));
// run
await controller.deleteIncomeSchedule(scheduleID);
// verify
verifyInOrder([
() => listener(data, any(that: isA<AsyncLoading>())),
() => listener(
any(that: isA<AsyncLoading>()), any(that: isA<AsyncError>())),
]);
verifyNoMoreInteractions(listener);
verify(() => deleteRepo.deleteIncomeSchedule(scheduleID)).called(1);
});
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
import 'package:suito/src/features/transactions/repositories/expense/delete_expense_repository.dart';
import 'package:suito/src/features/transactions/services/expense/delete_expense_controller.dart';

import '../../../../mocks.dart';

void main() {
ProviderContainer makeProviderContainer(MockDeleteExpenseRepository repo) {
final container = ProviderContainer(
overrides: [
deleteExpenseRepositoryProvider.overrideWithValue(repo),
],
);
addTearDown(container.dispose);
return container;
}

setUpAll(() {
registerFallbackValue(const AsyncLoading<int>());
});

group('deleteExpenseController', () {
test('delete expense, success', () async {
// setup
const expenseID = 'test_expense_id';
final deleteRepo = MockDeleteExpenseRepository();
when(() => deleteRepo.deleteExpense(expenseID)).thenAnswer(
(_) => Future.value(null),
);
final container = makeProviderContainer(deleteRepo);
final controller =
container.read(deleteExpenseControllerProvider.notifier);
final listener = Listener<AsyncValue<void>>();
container.listen(
deleteExpenseControllerProvider,
listener,
fireImmediately: true,
);
const data = AsyncData<void>(null);
verify(() => listener(null, data));
// run
await controller.deleteExpense(expenseID);
// verify
verifyInOrder([
() => listener(data, any(that: isA<AsyncLoading>())),
() => listener(any(that: isA<AsyncLoading>()), data),
]);
verifyNoMoreInteractions(listener);
verify(() => deleteRepo.deleteExpense(expenseID)).called(1);
});

test('delete expense, failure', () async {
// setup
const expenseID = 'test_expense_id';
final deleteRepo = MockDeleteExpenseRepository();
when(() => deleteRepo.deleteExpense(expenseID)).thenThrow(
(_) => Exception('Connection failed'),
);
final container = makeProviderContainer(deleteRepo);
final controller =
container.read(deleteExpenseControllerProvider.notifier);
final listener = Listener<AsyncValue<void>>();
container.listen(
deleteExpenseControllerProvider,
listener,
fireImmediately: true,
);
const data = AsyncData<void>(null);
verify(() => listener(null, data));
// run
await controller.deleteExpense(expenseID);
// verify
verifyInOrder([
() => listener(data, any(that: isA<AsyncLoading>())),
() => listener(
any(that: isA<AsyncLoading>()), any(that: isA<AsyncError>())),
]);
verifyNoMoreInteractions(listener);
verify(() => deleteRepo.deleteExpense(expenseID)).called(1);
});
});
}
12 changes: 12 additions & 0 deletions mobile/test/src/mocks.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import 'package:mocktail/mocktail.dart';
import 'package:suito/src/features/schedules/repositories/expense/delete_expense_schedule_repository.dart';
import 'package:suito/src/features/schedules/repositories/expense/expense_schedule_detail_repository.dart';
import 'package:suito/src/features/schedules/repositories/income/delete_income_schedule_repository.dart';
import 'package:suito/src/features/schedules/repositories/income/income_schedule_detail_repository.dart';
import 'package:suito/src/features/transactions/repositories/expense/delete_expense_repository.dart';
import 'package:suito/src/features/transactions/repositories/expense/expense_categories_repository.dart';
import 'package:suito/src/features/transactions/repositories/expense/expense_detail_repository.dart';
import 'package:suito/src/features/transactions/repositories/expense/expense_locations_repository.dart';
Expand All @@ -21,6 +24,15 @@ class MockExpenseLocationsRepository extends Mock

class MockIncomeTypesRepository extends Mock implements IncomeTypesRepository {}

class MockDeleteExpenseRepository extends Mock
implements DeleteExpenseRepository {}

class MockDeleteExpenseScheduleRepository extends Mock
implements DeleteExpenseScheduleRepository {}

class MockDeleteIncomeScheduleRepository extends Mock
implements DeleteIncomeScheduleRepository {}

class MockExpenseScheduleDetailRepository extends Mock
implements ExpenseScheduleDetailRepository {}

Expand Down

0 comments on commit 9e6e383

Please sign in to comment.