StockRecordUtility 職責被我定義為轉換 UI 輸入 到程式 Data Model 的物件,而 Date 轉換為 String 則為另一個物件的職責,這邊先把處理 Date 物件命名為 DateUtility。DateUtility
step1: 先寫測試,用前面所述的手法,將 Unit Testing class 開好
import XCTest
@testable import TwStockTools
final class DateUtilityTests: XCTestCase {
override func setUpWithError() throws {
}
override func tearDownWithError() throws {
}
}
step2: 使用固定的 unix time 來進行測試
/// 2023-09-05 05:09:55
private var timeInterval: TimeInterval {
1693890595
}
/// 2023-09-05 05:09:55
private var date: Date {
Date(timeIntervalSince1970: timeInterval)
}
step3: 寫 DateUtility 物件的測試,物件還沒實作時,仍然可以先寫測試
依需求,DateUtility 的界面為輸入 Date,輸出 String
func testDateToString() {
let sut = DateUtility()
let string = sut.getString(from: date)
let answer = "2023-09-05"
XCTAssertEqual(string, answer)
}
step4: 跑測試,讓錯誤發生
step5: 實作 getString(from date: Date) 並寫出能通過測試的版本
struct DateUtility {
func getString(from date: Date) -> String {
return "2023-09-05"
}
}
在step5,你可以看到直接將答案寫上去,或許有人會說「這麼不講武德,這樣你只會通過 unix time = 1693890595 的測項。
是的,所以,我們再加一個時間的測項,那原來的實作就會 test failed,接下來就是更改實作並通過所有測項。
step6: 加上第二個時間,並在測項上加第二個測試
/// 2023-09-06 01:43:45
private var timeIntervale2: TimeInterval {
1693964625
}
private var date2: Date {
Date(timeIntervalSince1970: timeIntervale2)
}
func testDateToString() {
let sut = DateUtility()
let string = sut.getString(from: date)
let answer = "2023-09-05"
XCTAssertEqual(string, answer)
let string2 = sut.getString(from: date2)
let answer2 = "2023-09-06"
XCTAssertEqual(string2, answer2)
}
step7: 跑測試
step8: 修正實作
struct DateUtility {
static let dateFormatter: DateFormatter = {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
return dateFormatter
}()
func getString(from date: Date) -> String {
return DateUtility.dateFormatter.string(from: date)
}
}
step9: 跑測試
step10: 將 StockRecordUtility 的 Date → String 轉換,改成 DateUtility 負責
/// 將 Date 轉換成 String,依 SRP 原則,這個工作應由 DateUtility 負責
let tradingDateStr = DateUtility().getString(from: tradingDate)
step11: 因為 StockRecordUtility 實作被更動了,需在更動後跑一次測試,確認修改的地方仍然能符合之前的 spec
測試全通過,這時候,我們就可以對 StockRecordUtility 的改動很有信心