サルだとわからん-やさしいSwift単体テスト 編集途中!
やさしいSwift単体テスト~テスト可能なクラス設計・後編~ - Qiita
そもそもテストとは
ざっくりいうと
入力値、引数を渡して、期待する結果も入力する。 そのとおり出力されるかをチェックする。
ポイント!
UIつまり、ビューと接続しているところは単体テストできない。必ずビューに依存しているので。
例えると結婚と筋肉トレーニングである。
あと1年以内に結婚すると決めたとしても、相手がいることなので、必ずしも結婚できるとは限らない。
そのようなものはテストできない。
しかし、筋肉トレーニングは、毎日時間を決めてやれば、必ず筋肉はつく。程度の差はあるが、、
同じように、画面と接続していると、StoryBoardが裏で(プログラムの影響範囲外)で動くので、基本単体テストはできない。
自動化して、できるようにすることもある。ここでは触れません。
だからMVVCの理論がある。
上記で赤のviewとつながっているところは、はテストできない しかし、緑と青のModel,Viewmodelはテスト可能。
ポイント
まずコードをViewとロジックで明確に切り分ける必要がある。
例 この関数をテストするとします。
まずこの関数はViewControllerに記載されているので、ViewControllerに依存しない、別クラスを作成します。
func HogeHoge(_ y : Int) { do{ let goals = try self.viewContext.fetch(goalQuery) if y == 0 { for goal in goals { goalList.insert(goal, at: 0) if goalList[0].image != nil { let buttonImage = UIImage(data: goalList[0].image as! Data) goButton.setImage(buttonImage, for: .normal) } //ここが良くない。Viewと接続している。ここを分離する。 self.mokuhyoLabel.text = goalList[0].name self.dateLabel.text = goalList[0].date! + "までに" //これはメンバに返却しているだけなので、OK self.x = 1 } } }catch{ print("フェッチできない") } }
修正後 詳細はコメントをみてください
class HogeHoge_test { //Viewに返す値を作成するためにstructを作成 //返却値を宣言 struct ReturnValue{ var x:Int var goButton:UIImage var mokuhyouLabel: String var dateLabel: String } let goalQuery: NSFetchRequest<Goal> = Goal.fetchRequest() var viewContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext //他で追加していないので var goalList: [Goal] = [] func getCoreData2(_ y : Int)-> ReturnValue? { do{ let goals = try self.viewContext.fetch(goalQuery) if y == 0 { for goal in goals { goalList.insert(goal, at: 0) } if goalList[0].image != nil { let buttonImage = UIImage(data: goalList[0].image as! Data) let returnValue = ReturnValue.init(x: 1, goButton: buttonImage!, mokuhyouLabel: goalList[0].name!, dateLabel: goalList[0].date!) // goButton.setImage(buttonImage, for: .normal) // self.mokuhyoLabel.text = goalList[0].name // self.dateLabel.text = goalList[0].date! + "までに" //self.x = 1 return returnValue } return nil }