SwiftでTDD写経　第7章 疑念をテストに翻訳する


6章の終わりでFrancとDollarを比較したらどうなるか？という疑念が湧いた。
で、実際に比較したところ、テストは失敗する。
つまり、ドルとフランが等しいとされてしまう。これはオブジェクトの比較の問題。
オブジェクトのクラスが同一かどうかの比較を行なっていないためである。

てなことでオブジェクトの型を比較します。


Equatableプロトコル使う場合はこんな感じ


```playground.swift

import UIKit


var moneytest = MoneyTest()

moneytest.TestMultiplication()
moneytest.TestEquality()
moneytest.TestFrancMultiplication()

class MoneyTest{
    init(){}

    func TestMultiplication(){
        var five = Dollar(5)
        assert(Dollar(10) == five.times(2))
        assert(Dollar(15) == five.times(3))
    }

    func TestEquality(){
        assert(Dollar(5) == Dollar(5))
        print("お")
        assert(Dollar(6) == Dollar(6))
        print("おわ")
        assert(Franc(5) == Franc(5))
        print("おわり")
        assert(Franc(6) == Franc(6))
        print("おわりだ")
        assert(Franc(6) != Franc(3))
        print("おわりだぞ")
        assert(Franc(6) != Dollar(6))
        print("おわりだぞ！")
       
    }
    
    func TestFrancMultiplication(){
        var five = Franc(5)
        assert(Franc(10) == five.times(2))
        assert(Franc(15) == five.times(3))
    }
}
///親クラス
class Money :Equatable{
    var amount:Int
    init(_ amount:Int){
        self.amount = amount
    }
    static func == (lhs: Money, rhs: Money) -> Bool {
        return lhs.amount == rhs.amount && type(of: lhs) == type(of: rhs)
    }
}

///Dollar子クラス
class Dollar:Money {
    override init(_ amount:Int){
        super.init(_ :amount)
        self.amount = amount
    }
    
    func times(_ multiplire:Int)  -> Dollar{
        return Dollar(amount * multiplire)
    }
}

///Franc子クラス
class Franc:Money {
    override init(_ amount:Int){
        super.init(_ :amount)
        self.amount = amount
    }
    
    func times(_ multiplire:Int)  -> Franc{
        return Franc(amount * multiplire)
    }
}

```

本書のような関数を使う場合はこんな感じ



```playground.swift
import UIKit


var moneytest = MoneyTest()

moneytest.TestMultiplication()
moneytest.TestEquality()
moneytest.TestFrancMultiplication()

class MoneyTest{
    init(){}
    
    func TestMultiplication(){
        var five = Dollar(5)
        print(5)
        assert(Dollar(15).equals(five.times(3)))
        assert(Dollar(10).equals(five.times(2)))
    }
    
    func TestEquality(){
        assert(Dollar(5).equals(Dollar(5)))
        print("お")
        assert(Dollar(6).equals(Dollar(6)))
        print("おわ")
        assert(Franc(5).equals(Franc(5)))
        print("おわり")
        assert(!Franc(6).equals(Franc(3)))
        print("おわりだ")
        assert(!Franc(6).equals(Dollar(6)))
        print("おわりだよ")
    }
    
    func TestFrancMultiplication(){
        var five = Franc(5)
        assert(Franc(15).equals(five.times(3)))
        assert(Franc(10).equals(five.times(2)))
    }
}

///親クラス
class Money {
    var amount:Int
    
    init(_ amount:Int){
        self.amount = amount
    }
    
    func equals(_ Object:Money) -> Bool{
        return Object.amount == self.amount
        && type(of: self) == type(of: Object)
    }
}


///Dollar子クラス
class Dollar:Money{
    
    override init(_ amount:Int){
        super.init(_ :amount)
        self.amount = amount
    }
    
    func times(_ multiplire:Int)  -> Dollar{
        return Dollar(amount * multiplire)
    }
}

///Franc子クラス
class Franc:Money{
    typealias classType = Franc
    
    override init(_ amount:Int){
        super.init(_ :amount)
        self.amount = amount
    }
    
    func times(_ multiplire:Int)  -> Franc{
        return Franc(amount * multiplire)
    }
}


```