Skip to content

Instantly share code, notes, and snippets.

@easylive1989
Created September 23, 2023 08:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save easylive1989/3008aea390455a660a7732bff4665dd2 to your computer and use it in GitHub Desktop.
Save easylive1989/3008aea390455a660a7732bff4665dd2 to your computer and use it in GitHub Desktop.
2023鐵人賽_D9_3
class CouponInvalidException implements Exception {}
class MoneyNotEnoughException implements Exception {}
import 'package:equatable/equatable.dart';
class NewYearCoupon extends Equatable {
@override
List<Object?> get props => [];
}
import 'package:equatable/equatable.dart';
class Product extends Equatable {
final double price;
const Product(this.price);
@override
List<Object?> get props => [price];
}
import 'product.dart';
class ProductRepository {
Future<void> purchase(Product product, coupon) async {}
}
import 'package:clock/clock.dart';
import 'product_repository.dart';
import 'product.dart';
import 'money_not_enough_exception.dart';
import 'coupon_invalid_exception.dart';
import 'wallet_repository.dart';
import 'new_year_coupon.dart';
class PurchaseProductService {
final ProductRepository productRepository;
final WalletRepository walletRepository;
PurchaseProductService(this.productRepository, this.walletRepository);
Future<void> execute(Product product, NewYearCoupon? coupon) async {
var now = clock.now();
if (_isUseCoupon(coupon) && !_isFirstOfJanuary(now)) {
throw CouponInvalidException();
}
var wallet = await walletRepository.get();
if (product.price > wallet.money) {
throw MoneyNotEnoughException();
}
productRepository.purchase(product, coupon);
}
bool _isFirstOfJanuary(DateTime now) => now.month == 1 && now.day == 1;
bool _isUseCoupon(NewYearCoupon? coupon) => coupon != null;
}
import 'package:clock/clock.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'product.dart';
import 'product_repository.dart';
import 'purchase_product_service.dart';
import 'purchase_product_service_test.mocks.dart';
import 'new_year_coupon.dart';
import 'wallet_repository.dart';
import 'wallet.dart';
@GenerateNiceMocks([MockSpec<ProductRepository>(), MockSpec<WalletRepository>()])
main() {
test("use coupon when purchase product", () async {
withClock(Clock.fixed(DateTime.parse('2023-01-01')), () async {
var mockProductRepository = MockProductRepository();
var mockWalletRepository = MockWalletRepository();
when(mockWalletRepository.get()).thenAnswer((_) async => Wallet(100));
var purchaseProductService = PurchaseProductService(mockProductRepository, mockWalletRepository);
await purchaseProductService.execute(
const Product(100),
NewYearCoupon());
verify(mockProductRepository.purchase(
const Product(100),
NewYearCoupon()),
).called(1);
});
});
}
class Wallet {
final double money;
Wallet(this.money);
}
import 'wallet.dart';
class WalletRepository {
Future<Wallet> get() async => Wallet(100);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment