在 Spock 框架中,如何从侦听器访问数据表变量"error"?



>我有一个数据表的测试,例如这样:

@Unroll
"Basic session start on platform = #platform"() {
    when: "user stats a session on a platform"
    def response = startSession(platform, id) // it does a REST request
    then: "response contains a userId"
    assert verifyUserId(response.userId) // method verifies userId with an internal algorithm and returns truefalse if it is valid or not
    where:
    id | platform
    1  | "Facebook"
    2  | "Google"
    3  | "Apple"
}

我还为错误编写了一个侦听器。

class MyListener extends AbstractListener {
...
   public void error(ErrorInfo error) { ... }
...
}

因此,如果在测试执行期间发生断言错误,代码将进入此"错误"方法。

问题是,如何从"错误"方法内部的"where"块中获取变量的值?

我不对数据表变量进行直接断言,因此 ErrorInfo.Exception 不包含它们。

我也找不到"ErrorInfo"对象的任何其他合适成员 - 我只能在 ErrorInfo.getMethod((.getFeature(( 中找到变量名称,但不能找到错误发生时它们的值。

这里的主要问题是 ErrorInfo 不提供当前的规范实例,这就是您无法获取迭代变量的原因。所以我建议两种方式:

第一个是使用迭代拦截器:

class ListenForErrorsExtension implements IGlobalExtension {
    void visitSpec(SpecInfo specInfo) {
        specInfo.addListener(new Listener())
        specInfo.allFeatures*.addIterationInterceptor(new IMethodInterceptor() {                      
            @Override
            void intercept(IMethodInvocation invocation) {
                holder.put(invocation.iteration.dataValues)
                invocation.proceed()
            }
        })
    }

第二个是Opal在评论中善意建议的。你可以瞬间不是AbstractRunListener,而是IRunListener

class ErrorExtension implements IGlobalExtension{
....
    @Override
    void beforeIteration(IterationInfo iteration) {       
        holder.put(iteration.dataValues)
    }
....
}

它使您可以访问每个迭代,但主要思想仍然如下:

您必须创建线程安全持有者,在错误发生之前将迭代数据放入其中,然后提取。

最新更新