Validate()返回false但已保存在数据库中

时间:2015-03-09 15:54:59

标签: grails gorm spock

我开始使用grails而且我偶然发现了一个我不理解的行为。

鉴于此域类

class Team {

    String name
    Date since
    Date until

    static hasMany = [teamMembers:Player]

    static constraints = {
        name nullable: false, blank: false, unique: true
        until nullable: true
        until(validator: { val, obj ->
            val?.after(obj.since)
        })

        teamMembers maxSize: 8
        //teamMembers size: 0..8
    }
}

我想进行一次集成测试,检查一个团队实际上不能超过8个玩家,所以我写了一个简化版本:

void "The team can only have up to 8 players"(){

    given:
    Player[] players = (1..9).collect {new Player(name: "Foo")}

    Team t = new Team(name:"Bar", since: new Date())

    expect:
    players.each {it.validate()}
    t.validate()

    when:

    players.each {it.save()}
    t.save()

    players.each {t.addToTeamMembers(it)}

    then:
    t.validate() == false
    t.getTeamMembers().size() == 9
    Team.get(t.id).teamMembers.size == 9
    Team.first().teamMembers.size == 9
    Team.findAll()[0].teamMembers.size == 9
    Team.findByName("Bar").teamMembers.size == 9
}

据我所知, get find *等命中数据库。那么为什么我的团队无法验证(预期行为),但数据库中有9个玩家? 我错过了什么?

注意:玩家名称不是PK,我已经测试了约束,大小和maxSize。

2 个答案:

答案 0 :(得分:1)

与此问题相关,I have found this answer from Peter Ledbrook

作为此链接的摘要:

  

...只要在Team对象上调用“save()”,就可以了   附在会议上。对该对象的任何后续更改都将   然后坚持到数据库,包括你添加的任何玩家

如果这是对的(我还没有真正尝试过),那应该解决它:

void "The team can only have up to 8 players"(){

given:
   Player[] players = (1..9).collect {new Player(name: "Foo")}

   Team t = new Team(name:"Bar", since: new Date())

expect:
   players.each {it.validate()}
   t.validate()

when:
   players.each {t.addToTeamMembers(it)}
   t.save()      

then:
   !t.validate()
}

这意味着只应保存一次团队对象(假设Player有一个到Team域类的belongsTo)。如果有效,请告诉我。

答案 1 :(得分:0)

这是一个错误吗? employees.each {t.addToTeamMembers(it)}
因为你没有employees变量。

假设你想说players.each {t.addToTeamMembers(it)}

我认为你需要在players.each {t.addToTeamMembers(it)}之后说t.save(),如果你想测试要坚持下去。

您的测试没有失败,因为您的团队规模为9,但实际上并没有为团队保存。

请尝试在when

之前保存