レコードデータの一部のフィールドだけテストする
レコードデータ型の一部のフィールドだけテストする方法について、以前から少し悩んでいた。
data Person = Person { id :: Int , name :: Text , age :: Int } deriving (Eq, Ord, Show) registerPerson :: Text -> Int -> IO Person
これをテストするために、例えば
let expected = Person 0 "taro" 18 got <- registerPerson "taro" 18 got `shouldBe` expected
などとやりたいところだが、registerPerson
は内部でid
をランダム生成するため、idに対してexpectationを書くことはできない。
かといって、name
とage
の各フィールドについてassertionを書き下すのも面倒だ。どうしたものか。
・・・よくよく考えてみればgotからexpectedを作ればいいのか。つまり
let expect p = p { name = "taro", age = 18 } got <- registerPerson "taro" 18 got `shouldBe` expect got
こうすれば、実質的にexpectで上書きしたフィールドでのみテストが実施されることになる。
また、expectはPerson -> Person
なのでMonoidとして扱うこともできる。組み合わせやすそうな気がする。
ただ、何かの間違いでexpect = id
にしてしまうとテストがザルになってしまい、コンパイラも見逃してしまうので注意。
もちろん、このやり方はテスト対象のレコード型が丸ごとEq
かつShow
じゃないと成立しない。そうでない場合はやはりめんどくさそうだ。