我正在尝试确保user
只能vote
给定project
一次(不允许重复投票)。经过一些搜索,看起来有一个composite unique constraint来实现这一目标。但是,我在集成测试中遇到了一些问题。我的域类如下。
package grailstuts
class User {
String name
static hasMany = [ projects: Project, votes: Vote ]
static constraints = { name(nullable: true) }
static mapping = { projects cascade: "all-delete-orphan" }
}
package grailstuts
class Project {
String title
Set votes = []
static belongsTo = [ user: User ]
static hasMany = [ votes: Vote ]
static constraints = { title(nullable: true) }
}
package grailstuts
class Vote {
static belongsTo = [ user: User, project: Project ]
static constraints = { user(unique: 'project') }
}
请注意unique
课程中的Vote
约束。然后我的集成测试看起来像这样:
package grailstuts
import spock.lang.*
class VoteIntegrationSpec extends Specification {
void "Testing uniqueness"() {
given: "A user and a project"
def user = new User();
def project = new Project();
user.addToProjects(project)
user.save(failOnError: true)
when: "The user votes the project"
def vote = new Vote()
user.addToVotes(vote)
project.addToVotes(vote)
then: "The user should not be able to vote the same project again"
def vote2 = new Vote()
user.addToVotes(vote2)
project.addToVotes(vote2)
}
}
此集成测试没有任何错误。但是我认为这个测试应该失败,因为用户再次投票给同一个项目(在then:
块中),这不应该基于static constraints = { user(unique: 'project') }
中的Vote
。类。似乎无法弄清楚这一点,任何人都可以指出我做错了什么吗?
感谢您的帮助。
答案 0 :(得分:2)
此行为的原因是未验证测试。
由于投票是针对每个用户和每个项目(我的假设),因为您说您需要复合唯一性:
package grailstuts
class Vote {
static belongsTo = [ user: User, project: Project ]
static constraints = {
user unique: 'project'
}
}
您的规范将是:
void "Testing uniqueness"() {
given: "A user and a project"
def user = new User()
def project = new Project()
user.addToProjects(project)
user.save(failOnError: true)
when: "The user votes the project"
def vote = new Vote(user:user,project:project).save()
then: "The user should not be able to vote the same project again"
// def vote2 = new Vote(user:user,project:project).save(flush:true,failOnError:true)
// or
new Vote(user:user,project:project).validate() == false
}
答案 1 :(得分:1)
您没有测试投票是否已保存到数据库。你应该:
when: ...
vote.save()
then: ...
Vote.count() == 1
when: ...
vote1.save()
then:
Vote.count() == 1 // Constraint working
你需要用两个时间和两个来编写测试。当保存第一次投票然后Vote.count()== 1当保存第二次投票然后Vote.count()== 1
您可以使用单元测试代替集成测试。执行效率更高。