使用 Spock 测试应用参数约束
Applying argument constraints with Spock tests
我已经为一些 Java 类 编写了 Spock 测试。当我尝试验证参数中使用的确切对象时,测试失败了。
def "all events are published to subscribers"() {
given:
EventSubscriber subscriber = Mock()
when:
subscriber.shouldRegister() >> true
subscriber.interests() >> new HashSet<Intent>(Arrays.asList(COUNTER, GAUGE))
publisher.subscribe(subscriber)
def event = publisher.newEvent("test", COUNTER)
event.start()
def child = event.newChild("child", GAUGE)
event.finish()
then:
// 2 * subscriber.onCreate(event)
// 1 * subscriber.onStart(event, event.start)
// 1 * subscriber.onEnd(event, event.end)
// 1 * subscriber.onChild(event, child)
2 * subscriber.onCreate(_)
1 * subscriber.onStart(_, _)
1 * subscriber.onEnd(_, _)
1 * subscriber.onChild(_, _)
}
注释掉的行失败
groovy.lang.MissingPropertyException: No such property: event for
class: io.hypi.faf.api.EventPublisherTest
at io.hypi.faf.api.EventPublisherTest.all events are published to
subscribers(EventPublisherTest.groovy:28)
http://spockframework.org/spock/docs/1.3/all_in_one.html#_argument_constraints 似乎暗示我可以传入一个值。第一个示例是一个字符串,但我认为类型无关紧要。
我做错了什么?
斯波克:1.3
Groovy:2.5
groovy-test-junit5-2.5.7
JDK: 11
交互测试中使用的对象实例应在 given
部分中定义。
这会起作用:
def 'all events are published to subscribers'() {
given:
EventSubscriber subscriber = Mock()
subscriber.shouldRegister() >> true
subscriber.interests() >> new HashSet<Intent>(Arrays.asList(COUNTER, GAUGE))
publisher.subscribe(subscriber)
def event = publisher.newEvent('test', COUNTER)
def child = event.newChild('child', GAUGE)
when:
event.start()
event.finish()
then:
2 * subscriber.onCreate(event)
1 * subscriber.onStart(event, event.start)
1 * subscriber.onEnd(event, event.end)
1 * subscriber.onChild(event, child)
}
但是测试 onCreate()
和 onChild()
的调用会出现问题,因为这些调用不在 when
部分,只有 onStart()
和onEnd()
可以匹配。
我没有你的 类 定义来查看详细信息,但我想 event.start
和 event.end
字段已在 start()
和 finish()
中初始化方法然后 1 * onStart(event, event.start)
和 1 * onEnd(event, event.end)
测试将不匹配,因为调用测试将在 event
具有不同的 start
和 end
值的阶段完成。那么只有 1 * onStart(event, _)
和 1 * onEnd(event, _)
测试才会匹配。
看看这个简单的例子,它与你的情况相似,但不同之处在于 event
实例是在 given
部分中准备的,而不是在 when
中修改的所以它将通过测试:
class InvocationWithArgumentsSpec extends Specification {
void 'Invocation test works with arguments other then String'() {
given:
def subscriber = Mock(Subscriber)
def simplePublisher = new Publisher()
simplePublisher.subscribe(subscriber)
def event = new SimpleEvent(name: 'test')
when:
simplePublisher.fireEvent(event)
then:
1 * subscriber.onEvent(event)
}
}
interface Subscriber {
void onEvent(SimpleEvent event)
}
class Publisher {
Subscriber subscriber
void subscribe(Subscriber subscriber) {
this.subscriber = subscriber
}
void fireEvent(SimpleEvent event) {
subscriber.onEvent(event)
}
}
class SimpleEvent {
String name
}
更新: 但是有一个解决方法适合您。它不是很好,但它可以工作并测试将正确的事件传递给订阅者方法(我猜 event
有类似 name
的东西):
def 'all events are published to subscribers'() {
given:
EventSubscriber subscriber = Mock()
subscriber.shouldRegister() >> true
subscriber.interests() >> new HashSet<Intent>(Arrays.asList(COUNTER, GAUGE))
publisher.subscribe(subscriber)
when:
def event = publisher.newEvent('test', COUNTER)
event.start()
event.newChild('child', GAUGE)
event.finish()
then:
1 * subscriber.onCreate({ it.name == 'test' })
1 * subscriber.onCreate({ it.name == 'child' })
1 * subscriber.onStart({ it.name == 'test' }, !null)
1 * subscriber.onEnd({ it.name == 'test' }, !null)
1 * subscriber.onChild({ it.name == 'test' }, { it.name == 'child' })
}
我已经为一些 Java 类 编写了 Spock 测试。当我尝试验证参数中使用的确切对象时,测试失败了。
def "all events are published to subscribers"() {
given:
EventSubscriber subscriber = Mock()
when:
subscriber.shouldRegister() >> true
subscriber.interests() >> new HashSet<Intent>(Arrays.asList(COUNTER, GAUGE))
publisher.subscribe(subscriber)
def event = publisher.newEvent("test", COUNTER)
event.start()
def child = event.newChild("child", GAUGE)
event.finish()
then:
// 2 * subscriber.onCreate(event)
// 1 * subscriber.onStart(event, event.start)
// 1 * subscriber.onEnd(event, event.end)
// 1 * subscriber.onChild(event, child)
2 * subscriber.onCreate(_)
1 * subscriber.onStart(_, _)
1 * subscriber.onEnd(_, _)
1 * subscriber.onChild(_, _)
}
注释掉的行失败
groovy.lang.MissingPropertyException: No such property: event for class: io.hypi.faf.api.EventPublisherTest
at io.hypi.faf.api.EventPublisherTest.all events are published to subscribers(EventPublisherTest.groovy:28)
http://spockframework.org/spock/docs/1.3/all_in_one.html#_argument_constraints 似乎暗示我可以传入一个值。第一个示例是一个字符串,但我认为类型无关紧要。
我做错了什么?
斯波克:1.3 Groovy:2.5 groovy-test-junit5-2.5.7 JDK: 11
交互测试中使用的对象实例应在 given
部分中定义。
这会起作用:
def 'all events are published to subscribers'() {
given:
EventSubscriber subscriber = Mock()
subscriber.shouldRegister() >> true
subscriber.interests() >> new HashSet<Intent>(Arrays.asList(COUNTER, GAUGE))
publisher.subscribe(subscriber)
def event = publisher.newEvent('test', COUNTER)
def child = event.newChild('child', GAUGE)
when:
event.start()
event.finish()
then:
2 * subscriber.onCreate(event)
1 * subscriber.onStart(event, event.start)
1 * subscriber.onEnd(event, event.end)
1 * subscriber.onChild(event, child)
}
但是测试 onCreate()
和 onChild()
的调用会出现问题,因为这些调用不在 when
部分,只有 onStart()
和onEnd()
可以匹配。
我没有你的 类 定义来查看详细信息,但我想 event.start
和 event.end
字段已在 start()
和 finish()
中初始化方法然后 1 * onStart(event, event.start)
和 1 * onEnd(event, event.end)
测试将不匹配,因为调用测试将在 event
具有不同的 start
和 end
值的阶段完成。那么只有 1 * onStart(event, _)
和 1 * onEnd(event, _)
测试才会匹配。
看看这个简单的例子,它与你的情况相似,但不同之处在于 event
实例是在 given
部分中准备的,而不是在 when
中修改的所以它将通过测试:
class InvocationWithArgumentsSpec extends Specification {
void 'Invocation test works with arguments other then String'() {
given:
def subscriber = Mock(Subscriber)
def simplePublisher = new Publisher()
simplePublisher.subscribe(subscriber)
def event = new SimpleEvent(name: 'test')
when:
simplePublisher.fireEvent(event)
then:
1 * subscriber.onEvent(event)
}
}
interface Subscriber {
void onEvent(SimpleEvent event)
}
class Publisher {
Subscriber subscriber
void subscribe(Subscriber subscriber) {
this.subscriber = subscriber
}
void fireEvent(SimpleEvent event) {
subscriber.onEvent(event)
}
}
class SimpleEvent {
String name
}
更新: 但是有一个解决方法适合您。它不是很好,但它可以工作并测试将正确的事件传递给订阅者方法(我猜 event
有类似 name
的东西):
def 'all events are published to subscribers'() {
given:
EventSubscriber subscriber = Mock()
subscriber.shouldRegister() >> true
subscriber.interests() >> new HashSet<Intent>(Arrays.asList(COUNTER, GAUGE))
publisher.subscribe(subscriber)
when:
def event = publisher.newEvent('test', COUNTER)
event.start()
event.newChild('child', GAUGE)
event.finish()
then:
1 * subscriber.onCreate({ it.name == 'test' })
1 * subscriber.onCreate({ it.name == 'child' })
1 * subscriber.onStart({ it.name == 'test' }, !null)
1 * subscriber.onEnd({ it.name == 'test' }, !null)
1 * subscriber.onChild({ it.name == 'test' }, { it.name == 'child' })
}