Как я могу имитировать запрос POST с телом json в SprayTest?

Если у меня есть конечная точка, которая распаковывает json следующим образом:

(path("signup")& post) {
    entity(as[Credentials]) { credentials =>
    …

Как я могу проверить это с помощью спецификации спрей-теста:

"The Authentication service" should {

"create a new account if none exists" in {
   Post("/api/authentication/signup", """{"email":"foo", "password":"foo:" }""") ~> authenticationRoute ~> check {
    handled === true
  }
}
}

Очевидно, что это не работает по нескольким причинам. Каким будет правильный путь?


person iwein    schedule 25.09.2013    source источник


Ответы (1)


Хитрость заключается в том, чтобы установить правильный Content-Type:

Post("/api/authentication/signup", 
    HttpBody(MediaTypes.`application/json`, 
          """{"email":"foo", "password":"foo" }""")
)

Но становится еще проще. Если у вас есть зависимость от spray-json, все, что вам нужно сделать, это импортировать:

import spray.httpx.SprayJsonSupport._
import spray.json.DefaultJsonProtocol._

первый импорт содержит (не) маршаллер, который преобразует вашу строку в запрос json, и вам не нужно оборачивать ее в HttpEntity с явным типом носителя.

второй импорт содержит все форматы чтения/записи Json для основных типов. Теперь вы можете написать просто: Post("/api/authentication/signup", """{"email":"foo", "password":"foo:" }"""). Но еще круче, если для этого у вас есть класс case. Например вы можете определить case class Credentials, предоставить для этого jsonFormat и использовать его в тестах/проекте:

case class Creds(email: String, password: String)
object Creds extends DefaultJsonProtocol {
  implicit val credsJson = jsonFormat2(Creds.apply)
}

сейчас в тесте:

Post("/api/authentication/signup", Creds("foo", "pass"))

спрей автоматически маршалирует его в запрос Json как application/json

person 4lex1v    schedule 25.09.2013
comment
Я считаю, что это больше не работает с последней версией. Вместо этого сделайте следующее: Post("/api/authentication/signup", HttpEntity(MediaTypes.`application/json`, """{"email":"foo", "password":"foo" }"""))) - person Grega Kešpret; 04.06.2014
comment
@GregaKešpret отлично работает с любой версией. Сейчас на спрее 1.3.1 с аккой 2.3.3 - person 4lex1v; 04.06.2014
comment
@AlexIv Где находится объект HttpBody? - person Grega Kešpret; 04.06.2014
comment
@GregaKešpret, когда вы импортируете SprayJsonSupport в область действия, он добавляет неявный маршаллер для объектов, для которых вы определили JsonFormat или RootJsonFormat. Задача этого упорядочивателя — преобразовать ваш объект в HttpEntity. - person 4lex1v; 04.06.2014