如何使用 Spock 以良好的方式(例如数据表)测试异常?
示例:有一个方法 validateUser
可以抛出不同消息的异常,或者如果用户有效则不抛出异常。
规范类本身:
class User { String userName }
class SomeSpec extends spock.lang.Specification {
...tests go here...
private validateUser(User user) {
if (!user) throw new Exception ('no user')
if (!user.userName) throw new Exception ('no userName')
}
}
变体 1
这个是可行的,但真正的意图被所有的 when/then 标签和 validateUser(user)
的重复调用弄得一团糟.
def 'validate user - the long way - working but not nice'() {
when:
def user = new User(userName: 'tester')
validateUser(user)
then:
noExceptionThrown()
when:
user = new User(userName: null)
validateUser(user)
then:
def ex = thrown(Exception)
ex.message == 'no userName'
when:
user = null
validateUser(user)
then:
ex = thrown(Exception)
ex.message == 'no user'
}
变体 2
由于 Spock 在编译时引发的这个错误,这个无法工作:
异常条件只允许出现在“then” block 中
def 'validate user - data table 1 - not working'() {
when:
validateUser(user)
then:
check()
where:
user || check
new User(userName: 'tester') || { noExceptionThrown() }
new User(userName: null) || { Exception ex = thrown(); ex.message == 'no userName' }
null || { Exception ex = thrown(); ex.message == 'no user' }
}
变体 3
由于 Spock 在编译时引发的这个错误,这个无法工作:
异常条件只允许作为顶级语句
def 'validate user - data table 2 - not working'() {
when:
validateUser(user)
then:
if (expectedException) {
def ex = thrown(expectedException)
ex.message == expectedMessage
} else {
noExceptionThrown()
}
where:
user || expectedException | expectedMessage
new User(userName: 'tester') || null | null
new User(userName: null) || Exception | 'no userName'
null || Exception | 'no user'
}
最佳答案
推荐的解决方案是有两种方法:一种测试好的情况,另一种测试坏的情况。那么这两种方法都可以利用数据表。
例子:
class SomeSpec extends Specification {
class User { String userName }
def 'validate valid user'() {
when:
validateUser(user)
then:
noExceptionThrown()
where:
user << [
new User(userName: 'tester'),
new User(userName: 'joe')]
}
def 'validate invalid user'() {
when:
validateUser(user)
then:
def error = thrown(expectedException)
error.message == expectedMessage
where:
user || expectedException | expectedMessage
new User(userName: null) || Exception | 'no userName'
new User(userName: '') || Exception | 'no userName'
null || Exception | 'no user'
}
private validateUser(User user) {
if (!user) throw new Exception('no user')
if (!user.userName) throw new Exception('no userName')
}
}
关于exception - Spock - 使用数据表测试异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19185596/