2015-01-09 1 views
6

나는 내 배우 인스턴스를 간첩하고 싶다. 그러나 단순히 새로운 키워드로 생성 할 수는 없다. 나는 해결책을 찾아 냈다.Akka 배우 mockito와 간첩하기

val testActorSpy = spy(TestActorRef(new TestActor).underlyingActor) 
    val testActorRef = TestActorRef(testActorSpy) 

그러나이 방법으로 하나의 불필요한 액터를 만든다. 클리너 솔루션이 있습니까?

답변

0

Akka Actor 시스템에 대한 나의 이해는 당신이 바로 다음의 속성을 통해 이것을해야한다는 것입니다.

따라서 Props를 통해 액터를 만들고 테스트중인 경우 액터로 스파이를 반환하십시오.

val testActorRef = TestActorRef(spy(new TestActor)) 
val testActorSpy = testActorRef.underlyingActor 

는 배우를 다시 시작할 때 underlyingActor가 파괴됩니다주의하십시오 :

따라서이 당신에게 결과를 제공한다. 그래서 이것을 조롱하는 것이 최선의 선택이 아닐 수도 있습니다.

액터를 직접 사용하지 않고 시스템을 직접 사용하는 경우 스레드 기반 시스템을 우회하여 테스트 할 수도 있습니다.

this (자바의 경우 코드 붙여 넣기)을 참조하십시오.

static class MyActor extends UntypedActor { 
    public void onReceive(Object o) throws Exception { 
    if (o.equals("say42")) { 
     getSender().tell(42, getSelf()); 
    } else if (o instanceof Exception) { 
     throw (Exception) o; 
    } 
    } 
    public boolean testMe() { return true; } 
} 

@Test 
public void demonstrateTestActorRef() { 
    final Props props = Props.create(MyActor.class); 
    final TestActorRef<MyActor> ref = TestActorRef.create(system, props, "testA"); 
    final MyActor actor = ref.underlyingActor(); 
    assertTrue(actor.testMe()); 
} 
+0

오직 액터의 공개 메소드는 'onReceive'이어야합니다. 그렇지 않으면, 불변성이 위험합니다. 이 경우,'testMe' 메소드가 액터의 상태를 수정하면, 그 원칙은 위반됩니다. 'testMe'는 비공개이어야합니다. JUnit 테스트에서 Spring을 사용하여 개인 메소드에 액세스하려면'ReflectionTestUtils'를 사용하십시오. –

+0

패키지를 비공개로 만듭니다. 가시성을 수정하는 방법은 수없이 많습니다. 코드베이스에서 작업하는 모든 사람들은 가변적 인 공유 상태가 좋지 않다는 것을 알고 있습니다. ActorRef는 공용 함수를 노출하지 않습니다. 그래서 그것은 문제가되지 않았습니다. 우리의 경쟁 조건은 개인 국가를 닫음으로써 왔습니다. – Alex

+0

당신 말이 맞습니다. 배우 내부의 공용 메소드는 노출되지 않습니다. 코드 냄새 같은 느낌이 들었습니다. 그러나 기능적 관점에서 당신은 옳습니다. 어쨌든 다른 누군가가 자신의 메서드를 비공개로 유지하려는 경우 'ReflectionTestUtils'를 사용하여 호출 할 수 있습니다. –