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

Если у меня есть конечная точка, которая unmarshalls 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
  }
}
}

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

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 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

Другие вопросы по тегам