Grails单元测试应该是奇怪的行为

时间:2013-12-07 20:14:44

标签: unit-testing validation grails constraints

Grails 2.3.4

给出以下域类:

class Player {

    String name

    static constraints = {
        name nullable: false, size: 2..30, unique: true
    }
}

运行以下单元测试会产生一些奇怪的行为。

使用shouldFail()进行测试

@Test
void nameUniqueContraint() {
    Player player = new Player(name: "John")
    Player player2 = new Player(name: player.name)
    assert(player.save())
    shouldFail(ValidationException) {
            player2.save(failOnError: true, flush: true)
            fail "FAIL ME"  
    }
}

测试结果:

  

grails.validation.ValidationException:发生了验证错误   在调用save()时:

     
      
  • 字段'name'上的对象'moonillusions.sulis.domain.Player'中的字段错误:被拒绝的值[John]
  •   

使用shouldFail()和catch

进行测试
@Test
void nameUniqueContraint1() {
    Player player = new Player(name: "John")
    Player player2 = new Player(name: player.name)
    assert(player.save())
    shouldFail(ValidationException) {
        try {
            player2.save(failOnError: true, flush: true)
            fail "FAIL ME"
        }catch(ValidationException e) {
            fail "CATCHED "
        }
    }
}

测试结果:

  

junit.framework.AssertionFailedError:CATCHED

使用catch进行测试

@Test
    void nameUniqueContraint2() {
        Player player = new Player(name: "John")
        Player player2 = new Player(name: player.name)
        assert(player.save())
        try {
            player2.save(failOnError: true, flush: true)
            fail "FAIL ME"
        }catch(ValidationException e) {
            fail "CATCHED "
        }
    }

测试结果:

  

junit.framework.AssertionFailedError:FAIL ME

对我来说,这些结果没有任何意义。 shouldFail()似乎没有表现出我们的预期(测试1),也影响了代码中的try块(测试2)。

1 个答案:

答案 0 :(得分:0)

此行为与某个示例中第一个“播放器”的刷新有关。当第二名球员脸红时,第一名球员的冲动可能正在发生。因此,根据我的理解,它会导致两个验证例外。

解决方案是在测试开始时冲洗第一个玩家。

@Test
void nameUniqueContraint() {
    Player player = new Player(name: "John")
    Player player2 = new Player(name: player.name)
    assert(player.save(failOnError: true, flush: true))
    shouldFail(ValidationException) {
            player2.save(failOnError: true, flush: true)
    }
}