Skip to content

Instantly share code, notes, and snippets.

@easylive1989
Created September 23, 2023 08:47
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/1c3a0f407cc430c8febfe69526ab88da to your computer and use it in GitHub Desktop.
Save easylive1989/1c3a0f407cc430c8febfe69526ab88da to your computer and use it in GitHub Desktop.
2023鐵人賽_D9_4
import 'package:equatable/equatable.dart';
class Coupon extends Equatable {
final double discount;
final DateTime expiredAt;
const Coupon({
required this.discount,
required this.expiredAt,
});
@override
List<Object?> get props => [discount, expiredAt];
}
class CouponInvalidException implements Exception {}
class MoneyNotEnoughException implements Exception {}
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 'product_repository.dart';
import 'product.dart';
import 'money_not_enough_exception.dart';
import 'coupon_invalid_exception.dart';
import 'wallet_repository.dart';
import 'coupon.dart';
class PurchaseProductService {
final ProductRepository productRepository;
final WalletRepository walletRepository;
PurchaseProductService(this.productRepository, this.walletRepository);
Future<void> execute(Product product, Coupon? coupon) async {
var now = DateTime.now();
if (coupon?.expiredAt.isBefore(now) ?? false) {
throw CouponInvalidException();
}
var wallet = await walletRepository.get();
if (product.price > wallet.money) {
throw MoneyNotEnoughException();
}
productRepository.purchase(product, coupon);
}
}
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 'coupon.dart';
import 'time_repository.dart';
import 'wallet_repository.dart';
import 'wallet.dart';
@GenerateNiceMocks([MockSpec<ProductRepository>(), MockSpec<WalletRepository>(), MockSpec<TimeRepository>()])
main() {
test("use coupon when purchase product", () async {
var mockProductRepository = MockProductRepository();
var mockWalletRepository = MockWalletRepository();
when(mockWalletRepository.get()).thenAnswer((_) async => Wallet(100));
var purchaseProductService = PurchaseProductService(mockProductRepository, mockWalletRepository);
const product = Product(100);
var coupon = Coupon(
discount: 0.5,
expiredAt: DateTime.now().add(const Duration(days: 10),
));
await purchaseProductService.execute(product, coupon);
verify(mockProductRepository.purchase(product, coupon)).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