我正在编写一个基本的玩家wallet
管理类,其中Integers
被添加(记入)或减去(借记)给玩家的钱包,其中错误被简单的try-catch
逻辑捕获。
注意:它仅用于处理
Integers
。
我试图将try-catch
逻辑抽象到这个Wallet类中;它应该处理credit
,debit
个动作,捕获错误并返回错误(如果找到)。
有没有办法将try-catch内容移动到类中然后返回错误?
让我们来看看这个例子:
我目前的班级是这样的:
enum WalletError : Error {
case mustBePositive
case notEnoughFunds
}
class Wallet {
public private(set) var balance: Int = 0
init(amount: Int = 0) {
self.balance = amount
}
func credit(amount: Int) throws {
guard amount > 0 else {
throw WalletError.mustBePositive
}
handleCredit(amount: amount)
}
func debit(amount: Int) throws {
guard amount > 0 else {
throw WalletError.mustBePositive
}
guard balance >= amount else {
throw WalletError.notEnoughFunds
}
guard (self.balance - amount >= 0) else {
throw WalletError.notEnoughFunds
}
handleDebit(amount: amount)
}
// MARK: (Private)
private func handleCredit(amount: Int) {
self.balance += amount
}
private func handleDebit(amount: Int) {
self.balance -= amount
}
}
测试借记操作,我有XCTest
函数
func testDebit() {
let w = Wallet()
XCTAssertTrue(w.balance == 0)
// Can't debit negative numbers
XCTAssertThrowsError(try w.debit(amount: -100)) { error in
XCTAssertEqual(error as? WalletError, WalletError.mustBePositive)
}
// can't debit money you don't have
XCTAssertThrowsError(try w.debit(amount: 100)) { error in
XCTAssertEqual(error as? WalletError, WalletError.notEnoughFunds)
}
// credit $100
XCTAssertNoThrow(try w.credit(amount: 100))
// debit $0 should throw error
XCTAssertThrowsError(try w.debit(amount: 0)) { error in
XCTAssertEqual(error as? WalletError, WalletError.mustBePositive)
}
// debit > balance should throw error
XCTAssertThrowsError(try w.debit(amount: 101)) { error in
XCTAssertEqual(error as? WalletError, WalletError.notEnoughFunds)
}
// debit $1 should be successful
XCTAssertNoThrow(try w.debit(amount: 1))
// balance should be 100-1 = $99
XCTAssertTrue(w.balance == 99)
}
当我编写应用程序时,我需要每次都编写try-catch块。
我希望Wallet类能够处理所有try-catch内容,并且只报告错误
我试过了:
// changes to wallet class
func canCredit(amount: Int) throws -> Bool {
guard amount > 0 else {
throw WalletError.mustBePositive
}
return true
}
func credit(amount: Int) -> Error? {
do {
if ( try canCredit(amount: amount) ) {
handleCredit(amount: amount)
}
return nil
} catch let error {
return error
}
}
但是现在XCTest
不知道投掷,我需要测试现在只返回true / false的canCredit。
此外,赠送金额会尝试返回错误,但我无法使用XCTAssertThrowsError()
有没有办法可以:
电子钱包类只应负责信用卡,借记卡和验证
将我所有的try-catch东西逻辑扔进这个类,所以我不必一直重复try-catch的东西?
我希望我已经澄清了这个问题。
谢谢
答案 0 :(得分:1)
创建函数throw
并移交错误
func credit(amount: Int) throws {
try canCredit(amount: amount)
handleCredit(amount: amount)
}
canCredit
成功,代码将转到下一行并处理信用。canCredit
失败,则会移交收到的错误并退出该功能。答案 1 :(得分:1)
您的目标似乎是抛出错误并将其转换为返回的错误。那个目标似乎错了。抛出是一种流控制形式。抛出错误是如何“向错误回复”给调用者。首先,你不应该想要你想要的东西。
不过,你可以肯定这样做。首先,保持您的credit(amount:)
和debit(amount:)
方法与第一个代码示例中的方法完全一致,以便您的单元测试可以测试它们。其次,在你的“真实代码”中,不要调用那些方法。相反,调用您提供的其他“包装器”方法,捕获抛出的错误并将其转换为返回的错误。
例如:
func realcredit(amount: Int) -> Error? {
do {
try credit(amount:amount)
return nil
} catch {
return error
}
}