きっかけ
コードのネストを深くするな | anopara を読んで、 僕もネストは浅い方が好きだけどisValid…お前はダメだ。 - bufferings のコメント / はてなブックマーク って書いたら、@m_seki さんに"isValidダメなんだ。どう書けばいいの?"というツッコミを頂いたので。ちょい考えてみた。まぁ、元記事の主題とは関係ないところなので。ゆるりとね。
元々のんは、こんな感じ?
Groovyで書いてみた。
class Data { def Count def Error def Result } class Validator { boolean isValid(Data a) { if(a != null) { if(a.Count > 0) { if(a.Error == null) { if (a.Result != null) return true; } } } return false; } }
で元記事のリファクタは
boolean isValid(Data a) { if (a == null) return false; if (a.Count > 0) return false; if (a.Error == null) return false; if (a.Result != null) return true; else return false; }
イケてない。なにがって。。。
リファクタするならテスト書こうね
Spockで書いてみた。こうですか?
class isValidメソッドのテスト extends spock.lang.Specification { def sut = new Validator() def "Dataがnullのときはfalse"() { setup: def data = null expect: sut.isValid(data) == false } @Unroll def "Count:#count, Error:#error, Result:#result のときは #valid"() { setup: def data = new Data(Count:count, Error:error, Result:result) expect: sut.isValid(data) == valid where: count | error | result || valid 0 | null | null || false 0 | null | "a" || false 0 | "a" | null || false 0 | "a" | "a" || false 1 | null | null || false 1 | null | "a" || true 1 | "a" | null || false 1 | "a" | "a" || false } }
Spock Web Console で実行すると。
こうなった。
isValidメソッドのテスト - Dataがnullのときはfalse - Count:0, Error:null, Result:null のときは false - Count:0, Error:null, Result:a のときは false - Count:0, Error:a, Result:null のときは false - Count:0, Error:a, Result:a のときは false - Count:1, Error:null, Result:null のときは false - Count:1, Error:null, Result:a のときは true - Count:1, Error:a, Result:null のときは false - Count:1, Error:a, Result:a のときは false
じゃ元記事のリファクタリング後のやつを
テストしてみようか。結果は。
isValidメソッドのテスト - Dataがnullのときはfalse - Count:0, Error:null, Result:null のときは false - Count:0, Error:null, Result:a のときは false - Count:0, Error:a, Result:null のときは false - Count:0, Error:a, Result:a のときは false FAILED Condition not satisfied: sut.isValid(data) == valid | | | | | | true | | false | | false | Data@441b9f Validator@112d0b5 at isValidメソッドのテスト.Count:#count, Error:#error, Result:#result のときは #valid(Script1.groovy:61) - Count:1, Error:null, Result:null のときは false - Count:1, Error:null, Result:a のときは true FAILED Condition not satisfied: sut.isValid(data) == valid | | | | | | false | | true | | false | Data@e75bc7 Validator@1f6c888 at isValidメソッドのテスト.Count:#count, Error:#error, Result:#result のときは #valid(Script1.groovy:61) - Count:1, Error:a, Result:null のときは false - Count:1, Error:a, Result:a のときは false
ふむ。2こ失敗しとるね。じゃ、修正すると、こうかな。
boolean isValid(Data a) { if (a == null) return false; if (a.Count <= 0) return false; if (a.Error != null) return false; if (a.Result != null) return true; else return false; }
テスト通った(∩´∀`)∩ワーイ
おまけ
テストがあるから安心して修正できるね!ってことで僕ならどう書くかなーって。
class Validator { boolean isValid(Data a) { return (a != null && a.Count > 0 && a.Error == null && a.Result != null) } }
こうかなー。(そういうことじゃない
全部入り
class Data { def Count def Error def Result } class Validator { boolean isValid(Data a) { return (a != null && a.Count > 0 && a.Error == null && a.Result != null) } } class isValidメソッドのテスト extends spock.lang.Specification { def sut = new Validator() def "Dataがnullのときはfalse"() { setup: def data = null expect: sut.isValid(data) == false } @Unroll def "Count:#count, Error:#error, Result:#result のときは #valid"() { setup: def data = new Data(Count:count, Error:error, Result:result) expect: sut.isValid(data) == valid where: count | error | result || valid 0 | null | null || false 0 | null | "a" || false 0 | "a" | null || false 0 | "a" | "a" || false 1 | null | null || false 1 | null | "a" || true 1 | "a" | null || false 1 | "a" | "a" || false } }