注意点としては、子の Domain は ID が同じものではなく、同じオブジェクトを使う事。
特に、Spockなど setup でターゲットとなる Domain を生成してる場合など注意。
通常 Domain の unique のテストは以下のようになる。
この場合は、Integer someNumber 単位でユニークになるだけなので単純。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Domainのクラス class UniqueDomain { Integer someNumber String name static constraints = { name unique : ["someNumber"] } } |
そのテスト
同じ Integer someNumber に対して同じ name を入れるだけ。
1 2 3 4 5 6 7 8 9 10 11 |
void testSomething() { def uniqueDomain = new UniqueDomain(someNumber: 1, name : "test") mockForConstraintsTests(UniqueDomain, [uniqueDomain]) def uniqueDomainError = new UniqueDomain(someNumber: 1, name : "test") assertFalse uniqueDomainError.validate() assertEquals "unique", uniqueDomainError.errors["name"] } |
結果は、 同じ someNumber の時に同じ name は入らないので unique エラーになる。
この someNumber が Integer が他の Domain の場合(親子関係にある場合) 以下のようになる。
子となる Domain の定義
1 2 3 4 5 6 7 |
class ChildDomain { static constraints = { } } |
UniqueDomain の someNumber を上で定義した子 Domain にして 親子関係にする。さらに unique 制約も ChildDomain 単位にする
1 2 3 4 5 6 7 8 9 10 11 12 |
class UniqueDomain { ChildDomain childDomain String name static constraints = { name unique : ["childDomain"] } } |
テストは以下のようになる。
同じ子の Domain に対して同じ name を付ければエラーとなる確認。
1 2 3 4 5 6 7 8 9 10 11 |
void testSomething() { def uniqueDomain = new UniqueDomain(someNumber: 1, name : "test") mockForConstraintsTests(UniqueDomain, [uniqueDomain]) def uniqueDomainError = new UniqueDomain(someNumber: 1, name : "test") assertFalse uniqueDomainError.validate() assertEquals "unique", uniqueDomainError.errors["name"] } |
Spockを使っている時に、以下のようにすると間違い。
ID が同じでも、別のオブジェクトだと駄目。 setup と、 実際のテストで別のオブジェクトを生成してしまっている。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
def setup() { ChildDomain childDomain = new ChildDomain(); childDomain.id = 1 def uniqueDomain = new UniqueDomain(childDomain: childDomain, name : "test") mockForConstraintsTests(UniqueDomain, [uniqueDomain]) } void testSomething() { given: ChildDomain childDomain = new ChildDomain(); childDomain.id = 1 def uniqueDomainError = new UniqueDomain(childDomain: childDomain, name : "test") when: uniqueDomainError.validate() then: assertFalse uniqueDomainError.validate() assertEquals "unique", uniqueDomainError.errors["name"] } |
正しくは、ChildDomain は使いまわせるように宣言しておくとよい。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
ChildDomain childDomain def setup() { childDomain = new ChildDomain(); childDomain.id = 1 def uniqueDomain = new UniqueDomain(childDomain: childDomain, name : "test") mockForConstraintsTests(UniqueDomain, [uniqueDomain]) } void testSomething() { setup: def uniqueDomainError = new UniqueDomain(childDomain: childDomain, name : "test") when: uniqueDomainError.validate() then: assertFalse uniqueDomainError.validate() assertEquals "unique", uniqueDomainError.errors["name"] } |