문제

스칼라 배우를 테스트하는 좋은 방법을 아는 사람이 있습니까? 일반적으로 나는 메시지를 받고 응답으로 다른 메시지를 보내는 배우가 있습니다. 이것은 여러 스레드에서 이루어지며 올바른 배우는 잘못된 메시지를 보내거나 메시지가 전혀 없을 수 있습니다. 테스트중인 배우에게 메시지를 보내고받는 모형 배우를 만드는 간단한 방법이 필요합니다. 이 분야에서 경험이 있습니까?

도움이 되었습니까?

해결책

배우 스타일의 메시지 통과의 역동적 인 특성으로 인해 조롱하는 배우는 일반적으로 문제가되지 않습니다. 원하는 메시지를받는 배우 만 만들면 집에 무료로 집에 있습니다. 물론이 모의 배우가 메시지가 전달되는 행위자인지 확인해야하지만 테스트를 시도하는 배우가 다음과 같은 한 문제가되지 않아야합니다. 요각.

다른 팁

복잡성은 몇 가지 요인에 달려 있다고 생각합니다 ...

  1. 배우는 얼마나 상태가 있습니까?

Idempotent 함수처럼 작동하는 경우 비동기만으로도 메시지를 보내는 배우를 조롱 한 다음 예상 메시지를 다시 받는지 확인하는 간단한 문제 여야합니다. 교수형이 아닌 합리적인 시간 내에 응답이있을 경우 모의 배우에 반응/수신을 사용하고 싶을 것입니다.

그러나 메시지가 서로 독립적이지 않으면 다양한 메시지와 예상 결과로 테스트해야합니다.

  1. 테스트를받는 배우는 얼마나 많은 배우가 상호 작용합니까?

배우가 다른 많은 사람들과 상호 작용할 것으로 예상되고 상태가 높으면 메시지를 보내거나받는 여러 배우와 함께 테스트해야합니다. 메시지가 도착하는 순서를 보장하지 않으므로 배우가 메시지를 보내는 순서를 분출 시키거나 행위자가 메시지를 생성하는 행위자에서 임의의 일시 정지를 도입하고 여러 번 테스트를 실행해야합니다.

나는 배우기를위한 미리 빌드 프레임 워크를 알지 못하지만 영감을 얻기 위해 Erlang을 찾을 수 있습니다.

http://svn.process-one.net/contribs/trunk/eunit/doc/overview-summary.html

배우를 직접 테스트하는 방법에 대해 궁금했습니다.

여기에 내가 생각해 낸 것이 있습니다. 아무도이 접근법에 문제가 있습니까?

메시지를 직접 보내지 않고 배우가 기능으로 보내는 메시지를 위임 한 경우 어떻게해야합니까?

그런 다음 테스트는 호출 된 시간 수 및/또는 메소드가 불리는 인수를 추적하는 기능으로 기능을 교체 할 수 있습니다.

class MyActor extends Actor {

  var sendMessage:(Actor, ContactMsg) => Unit = {
    (contactActor, msg) => {
      Log.trace("real sendMessage called")
      contactActor ! msg 
    }
  }

  var reactImpl:PartialFunction(Any, Unit) = {
      case INCOMING(otherActor1, otherActor2, args) => {

        /* logic to test */
        if(args){
          sendMessage(otherActor1, OUTGOING_1("foo"))

        } else {
          sendMessage(otherActor2, OUTGOING_2("bar"))
        }
      }
  }

  final def act = loop {
    react {
      reactImpl
    }
  }

테스트 케이스는 다음과 같은 코드가 포함될 수 있습니다.

// setup the test
var myActor = new MyActor
var target1 = new MyActor
var target2 = new MyActor
var sendMessageCalls:List[(Actor, String)] = Nil

/*
* Create a fake implementation of sendMessage
* that tracks the arguments it was called with
* in the sendMessageCalls list:
*/
myActor.sendMessage = (actor, message) => {
  Log.trace("fake sendMessage called")
  message match {
    case OUTGOING_1(payload) => { 
      sendMessageCalls = (actor, payload) :: sendMessageCalls
    }
    case _ => { fail("Unexpected Message sent:"+message) }
  }
}

// run the test
myActor.start
myActor.reactImpl(Incoming(target1, target2, true))

// assert the results
assertEquals(1, sendMessageCalls.size)
val(sentActor, sentPayload) = sendMessageCalls(0)
assertSame(target1, sentActor)
assertEquals("foo", sentPayload)
// .. etc.

유닛 테스트 배우를 테스트하려는 시도 (작동). 사용 중입니다 명세서 프레임 워크로.

object ControllerSpec extends Specification {
  "ChatController" should{
    "add a listener and respond SendFriends" in{
        var res = false
        val a = actor{}
        val mos = {ChatController !? AddListener(a)}
        mos match{
             case SendFriends => res = true
             case _ => res = false
        }
        res must beTrue
    }

이것이 어떻게 작동 하는가는 Singleton ChatController에 동기 호출을 보내는 것입니다. ChatController는 사용하여 응답합니다 댓글(). 응답은 호출 된 함수의 반환으로 전송되며, 이는 MOS에 저장됩니다. 그런 다음 ChatController에서 전송 된 사례 클래스를 얻는 MOS에 일치하는 것이 적용됩니다. 결과가 예상되는 것 (SendFriends)이 RES를 true로 설정합니다. 그만큼 RES는 배신해야합니다 주장은 시험의 성공 또는 실패를 결정합니다.

내가 테스트하는 배우 싱글 톤

import ldc.socialirc.model._

import scala.collection.mutable.{HashMap, HashSet}
import scala.actors.Actor
import scala.actors.Actor._

import net.liftweb.util.Helpers._

//Message types
case class AddListener(listener: Actor)
case class RemoveListener(listener: Actor)
case class SendFriends
//Data Types
case class Authority(usr: Actor, role: String)
case class Channel(channelName: String, password: String, creator: String, motd:   String, users: HashSet[Authority])

object ChatController extends Actor {
    // The Channel List  - Shows what actors are in each Chan
    val chanList = new HashMap[String, Channel]
    // The Actor List - Shows what channels its in
    val actorList = new HashMap[Actor, HashSet[String]]

    def notifyListeners = {

    }

    def act = {
        loop {
            react {
                case AddListener(listener: Actor)=>
                    actorList += listener -> new HashSet[String]
                    reply(SendFriends)

            }
        }
    }
    start //Dont forget to start
}

완전하지는 않지만 예상대로 Sendfriends Case 클래스를 반환합니다.

행위자의 단위 테스트를위한 스위트 룸은 최근에 추가되었습니다. Akka. 정보 및 코드 스 니펫을 찾을 수 있습니다 이것 블로그 게시물.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top