【发布时间】:2013-10-11 17:02:27
【问题描述】:
如何使用 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”块中
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'
}
【问题讨论】:
-
上周遇到了同样的情况,我完全按照@peter 的建议做了。 :) 基于一个数据表处理两种异常变体(抛出/未抛出)不是方法。你甚至不能在数据表中抛出异常。
标签: exception testing groovy spock