iT邦幫忙

2023 iThome 鐵人賽

DAY 15
0
Mobile Development

在 iOS 專案上加上 Unit testing - 因為 You need testing系列 第 15

D15 - 在 iOS 專案加上測試-You need testing {單一責則原則 - DateUtility}

  • 分享至 

  • xImage
  •  

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: 跑測試,讓錯誤發生

https://ithelp.ithome.com.tw/upload/images/20230926/201406228FmgQJJHfD.png

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: 跑測試

https://ithelp.ithome.com.tw/upload/images/20230926/20140622LnXDCPAnSF.png

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: 跑測試

https://ithelp.ithome.com.tw/upload/images/20230926/20140622Q8SzI3IpEe.png

step10: 將 StockRecordUtility 的 Date → String 轉換,改成 DateUtility 負責

/// 將 Date 轉換成 String,依 SRP 原則,這個工作應由 DateUtility 負責
        let tradingDateStr = DateUtility().getString(from: tradingDate)

step11: 因為 StockRecordUtility 實作被更動了,需在更動後跑一次測試,確認修改的地方仍然能符合之前的 spec

https://ithelp.ithome.com.tw/upload/images/20230926/20140622WqG40MHUOd.png

測試全通過,這時候,我們就可以對 StockRecordUtility 的改動很有信心


上一篇
D14 - 在 iOS 專案加上測試-You need testing {台股小工具 app-加上日期}
下一篇
D16 - 在 iOS 專案加上測試-You need testing {台股小工具 app- test in Combine}
系列文
在 iOS 專案上加上 Unit testing - 因為 You need testing32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言