2017-11-13 18 views
1

데이터 표가있는 테스트가 있습니다. like :Spock 프레임 워크에서 "오류"리스너의 데이터 테이블 변수에 어떻게 액세스합니까?

@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 true\false if it is valid or not 

    where: 
    id | platform 
    1 | "Facebook" 
    2 | "Google" 
    3 | "Apple" 
} 

나는 또한 오류에 대한 청취자를 작성했습니다.

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

테스트 실행 중에 어설 션 오류가 발생하는 경우 코드가이 "오류"방법으로 넘어갑니다.

질문은 "오류"방법에서 "블록"의 변수 값을 어떻게 얻을 수 있습니까?

데이터 테이블 변수에 대한 직접적인 어설 션을 수행하지 않기 때문에 ErrorInfo.Exception에 포함되지 않습니다.

"ErrorInfo"개체의 다른 적합한 구성원을 찾을 수 없습니다. ErrorInfo.getMethod(). getFeature()에서만 변수 이름을 찾을 수 있지만 오류가 발생했을 때는 그 값이 없습니다.

+3

전체 샘플 사양을 제공해 주시겠습니까? – Opal

+0

피쳐 메서드의 전체 샘플을 제공했습니다. 이것이 의미하는 것입니까? 사양 그냥 클래스에 래핑, 내 경우에는 어떤 setups \ cleanups가 필요하지 않습니다. – Ubeogesh

+1

[It] (https://github.com/Opalo/stackoverflow/tree/master/47270731) (_It_ - 링크가 있습니다.) 그것이 당신이 찾고있는 것이고 스레드 안전성이 있는지는 전혀 모른다. 그것을 밖으로 시도하십시오. – Opal

답변

0

여기에서 가장 중요한 문제는 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() 
      } 

     }) 
    } 

:

첫 번째 반복 인터셉터를 사용하는 것입니다.

당신은 스레드 안전 홀더를 만들 필요가

, 오류 전에 그것을 iterration 데이터를 입력 : 당신은 당신이 각 iterration에 액세스 할 수 있지만, 주요 아이디어는 여전히 따르고 IRunListener

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

을하지 AbstractRunListener instantinate하지만, 수 그런 다음 추출했습니다.

+0

감사합니다! 나는 반복 인터셉터를 사용했다. 홀더 대신에 리스너에 Object 변수를 만들고 인터셉트 메서드 내에서 값 (dataValues)을 할당했습니다. 그 후 "error"에 사용했습니다. 내가 아는 한 (전 총 noob btw) 리스너는 spec마다 만들어지기 때문에 스레드 안전 홀더가 실제로 필요하지 않습니다. 우리의 경우에는 specs가 1 스레드로 실행됩니다. – Ubeogesh

+0

@Ubeogesh 그것이 도움이되기를 바랍니다. D Btw는 항상 의존하지만 일반적으로 사람들은 여러 스레드에서 실행하여 회귀 시간을 줄이려고합니다. 그것이 스레드 안전을 제안한 이유입니다. –

+0

우리는 여러 스레드에서 테스트를 실행합니다 - 그러나 이들은 스펙과 병렬 처리됩니다 (각 스펙은 자체 리스너 \ iterationInterceptor를가집니다) – Ubeogesh