Tastable

Tastable

Posted by willsbor Kang on 2017-04-28

所以維持程式的穩定是我們目的,實作測試碼是我的方法。

過去在 ObjectC 上有很方便的方法 method swizzling,因為語言的特性,可以直接動態替換掉 method,

但是在 swift 上,就不能這樣做了!

而是要在寫程式的一開始,就要設計整個架構,讓他是可以測試的。

接續著 2017-04-19 中的例子,考慮測試範圍是自己寫的邏輯部分,進而重新定義題目:

  • 我要實作一個讓使用者訂閱離線資料庫、自動更新的功能,除了操縱邏輯外,還需要有一個能提供付費的機制,而系統內建的購買功能正好能提供這項服務

依據題目,可能可以將程式碼寫成下面這樣

我要實作一個讓使用者訂閱離線資料庫、自動更新的功能:

1
2
3
4
5
6
7
8
9
class BuyViewController: UIViewController {
...

func clickBuyButton() {
MyManager.sharedInstance.buy { (error) -> Void in
...
}
}
}

除了操縱邏輯外,還需要有一個能提供付費的機制:

1
2
3
4
5
6
7
8
9
10
11
protocol MyBuyMethod {
func purchase(_ completionHandler: ((error) -> Void))
}

class MyManager {
var buyMethod: MyBuyMethod!

func buy(_ completionHandler: ((error) -> Void)?) {
buyMethod.purchase(completionHandler)
}
}

而系統內建的購買功能正好能提供這項服務:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class BuyFromSystem: MyBuyMethod, SystemBuyDelegate {

var completionHandler: ((error) -> Void)?

func purchase(_ completionHandler: ((error) -> Void)?) {
self.completionHandler = completionHandler
SystemBuy.default.delegate = self
SystemBuy.default.buy()
}

//:- SystemBuyDelegate

func buySuccess() {
completionHandler?(nil)
}

func buyFailed(error: Error) {
completionHandler?(error)
}
}

上面的程式碼看起來,似乎只是多寫了一個 protocol (介面),這樣究竟有什麼差別呢?

依據前一篇說的,系統或第三方提供方法,其實不是我們要測試的範圍,所以上面的寫法,很明確的把系統購買這件事情切分在 BuyFromSystem 這個物件中,而我們自己寫的邏輯,就乾淨的存在在 MyManager 中。

測試時需要假造資料的接口也存在了 var buyMethod: MyBuyMethod!

Finish Date: 2017-05-10