2015-03-01 2 views
0

Если мне нужно написать интеграционный тест с использованием HTTP-запроса через брызговик, как я могу убедиться, что спрей-блэк использует CallingThreadDispatcher?Akka IO и TestActorRef

В настоящее время следующий актер напечатает None

class Processor extends Actor { 
    override def receive = { 
    case Msg(n) => 
     val response = (IO(Http) ? HttpRequest(GET, Uri("http://www.google.com"))).mapTo[HttpResponse] 
     println(response.value) 
    } 
} 

Как я могу убедиться, что запрос выполняется в том же потоке, что и испытание (в результате синхронного запроса)?

ответ

1

Похоже, странный способ интегрировать внутреннее тестирование, так как вы не издеваетесь над «Google», поэтому больше похоже на интеграцию внешнего тестирования и синхронного TestActorRef. Требование контролировать потоки внутри спрея также довольно сложно. Однако, если вам действительно нужно это для http-request - это возможно. В общем случае, вы должны установить несколько диспетчеров в вашем application.conf:

  • «менеджер-диспетчер» (от Http.scala) направить свой IO(Http) ? req
  • «хост-разъем-диспетчеру», чтобы использовать его HttpHostConnector (или ProxyHttpHostConnector), который на самом деле послать ваш запрос
  • «Настройка-группы диспетчерская» для Http.Connect

всех они в Configuration Section проделать описанные распылительную документацию. И все они указывают на «akka.actor.default-dispatcher» (см. Dispatchers), поэтому вы можете изменить их все, изменив это.

Проблема заключается в том, что вызов нитки не гарантированно будет вашей нитью на самом деле, поэтому он не поможет многим вашим тестам. Только представьте, если некоторые из актеров регистрируют некоторый обработчик, отвечая на Ваше сообщение:

//somewhere in spray... 
    case [email protected] => registerHandler(() => { 
     ... 
     sender ! response 
    }) 

Ответ может быть отправлен из другого потока, поэтому response.value все еще может быть None в токе. Фактически, ответ будет отправлен из прослушивающей нити базовой библиотеки сокетов, независимо от потока вашего теста. Просто говоря, запрос может быть отправлен в одном (вашем) потоке, но ответ получен в другом.

Если вам действительно нужно блокировать здесь, я бы рекомендовал вам переместить такие образцы кода (например, IO(Http) ? HttpRequest) и издеваться над ними любым удобным способом в ваших тестах. Smtng так:

trait AskGoogle { 
    def okeyGoogle = IO(Http) ? HttpRequest(GET, Uri("http://www.google.com"))).mapTo[HttpResponse] 
} 

trait AskGoogleMock extends AskGoogle { 
    def okeyGoogle = Await.result(super.okeyGoogle, timeout) 
} 

class Processor extends Actor with AskGoogle { 
    override def receive = { 
    case Msg(n) => 
     val response = okeyGoogle 
     println(response.value) 
    } 
} 

val realActor = system.actorOf(Props[Processor]) 
val mockedActor = TestActorRef[Processor with AskGoogleMock] 

Кстати, вы можете издеваться IO(HTTP) с другим TestActorRef в пользовательском актер, который будет делать внешние запросы для вас - она ​​должна требовать минимальных изменений коды, если у вас есть большой проект.

+0

Это, вероятно, именно то, что я искал. Это вполне разумно, используя версию Await.result в тестах. Благодарю. –

Смежные вопросы