2013-05-12 3 views
12

암묵적인 매개 변수가 관련되어있을 때 스칼라에서 테스트를 작성하는 방법을 이해하려고 힘든 시간을 보내고 있습니다.암시 적 매개 변수를 조롱하는 스칼라 테스트?

내 코드와 테스트의 다음 (짧은 버전)이 있습니다

구현 (스칼라 2.10, 스프레이 및 Akka) : (ScalaTest 및 Mockito 사용)

import spray.httpx.SprayJsonSupport._ 
import com.acme.ResultJsonFormat._ 

case class PerRequestIndexingActor(ctx: RequestContext) extends Actor with ActorLogging { 
    def receive = LoggingReceive { 
    case AddToIndexRequestCompleted(result) => 
     ctx.complete(result) 
     context.stop(self) 
    } 
} 


object ResultJsonFormat extends DefaultJsonProtocol { 
    implicit val resultFormat = jsonFormat2(Result) 
} 

case class Result(code: Int, message: String) 

테스트 :

"Per Request Indexing Actor" should { 
    "send the HTTP Response when AddToIndexRequestCompleted message is received" in { 
     val request = mock[RequestContext] 
     val result = mock[Result] 

     val perRequestIndexingActor = TestActorRef(Props(new PerRequestIndexingActor(request))) 
     perRequestIndexingActor ! AddToIndexRequestCompleted(result) 

     verify(request).complete(result) 
    } 
    } 

이 줄의 verify(request).complete(result)은 암시 적 Marshaller를 사용하여 Result을 JSON으로 변환합니다.

implicit val marshaller: Marshaller[Result] = mock[Marshaller[Result]]을 추가하여 marshaller를 가져올 수 있지만 테스트를 실행할 때 Marshaller의 다른 인스턴스가 사용되므로 확인이 실패합니다.

명시 적으로 모의 Marshaller를 complete으로 전달하더라도 실패합니다.

암시 적 매개 변수에 대한 mock 객체를 만드는 방법을 조언하고 인스턴스가 사용 된 인스턴스인지 확인하십시오.

+0

명시 적으로 모의를 통과하는 데 어떻게 실패합니까? 왜 처음에는 모의 마샬 러를 사용하고 싶습니까? (나는 모치 토를 사용하지 않았기 때문에 바보 같은 질문이라면 실례합니다.) – jrudolph

답변

5

마샬 러 arg에 Mockito의 Matcher을 사용하는 것이 가장 좋은 상황입니다. 암묵적인 마샬 러를 조롱 할 필요는 없습니다. 정말로 원하는 것은 complete이 예상 한 것과 일치하는 result과 마샬 러의 일부 인스턴스와 함께 호출되었는지 확인하는 것입니다. 당신이 이미하지 않은 경우 첫째,과 같이 가져 오기로 Mockito이 범위에 정합 가지고 :

import org.mockito.Matchers._ 

을 그런 다음 결과에 참조 일치를 원한다면, 당신과 같이 확인할 수 :

을 당신은 당신이 원하는 경우
verify(request).complete(same(result))(any[classOf[Marshaller[Result]]]) 

또는, 결과에 일치하는 동일을 할 수있는 :

verify(request).complete(eq(result))(any(classOf[Marshaller[Result]])) 

매처 (matcher)와 트릭은 당신이 하나 개의 인수에 대해 하나를 사용하면 그 이유는 그래서, 당신은 모든 인수를 위해 그들을 사용해야한다는 것입니다 우리는 o result에도 하나를 사용하십시오.

+0

나는 그것을 시도해 보았습니다. 필자는'same()'매처를 사용하지는 않았지만. 나는 (검증) .complete (same (result)) (모든 [classOf [Marshaller [Result]])')를 사용할 때 왜 테스트가 통과 하는지를 확신하지 못한다. 그러나 verify (request) .complete (eq (result)) (any (classOf [Marshaller [Result]]))'. 귀하의 제안에 감사드립니다, 그것은 도왔습니다 :) – C0deAttack

+0

요청 변수 자체가 모의이기 때문에 eq matcher는 스텁되지 않은 equals 메소드를 사용하므로 항상 false가되므로 일치하지 않습니다. 같은 것이 여기에 적합합니다. 요청이 모의 사례가 아니고 일부 사례 클래스가 아닌 경우 eq가 더 잘 맞을 수도 있습니다. – cmbaxter

+1

후속 조치에 감사드립니다. 명확하지 않은 것에 대해 사과드립니다. 'eq'를 사용하면 테스트가 컴파일되지 않습니다. 'eq'를 사용할 때 에러 메시지는 "Marshaller [Boolean], Marshaller [Result]"와 같은 예상되는 타입 불일치입니다. 'any (classOf [Marshaller [Result]]) '에 오류가 있습니다. 나는 왜 오류가 발생하는지 100 % 명확하지 않다. 그것은 꽤 이상합니다. – C0deAttack

관련 문제