3

ご指導ありがとうございました!

SecureSocial プラグインは、ブラウザから実行すると正常に動作しますが、Play アプリの残りの部分を今すぐテストできるようにしたいと考えています。

クイックイントロ

SecureSocial の構文は次のようになります。

def page = SecuredAction(WithProvider("google")) { ... }

またはこれ:

def page = UserAwareAction { ... }

これは、SecureSocial に関する私の問題にリモートで関連していても、スタック オーバーフローに関する唯一の質問のようですが、バイトコードを再配線することはあまり好きではありませんこれにはもっと簡単な解決策があるはずです。

SecureSocial で保護されたアクションにアクセスするテストを実行しているときに、大きなエラーが発生しました。これは基本的に、ユーザーに渡していないことを意味していると推測されます。(この質問の下部を参照)

やりたいこと

すべての関数を注入して型を返すAction代わりに、SecuredActionまたはUserAwareActionテスト中にのみ型を返す

または、実際にテスト ユーザーを呼び出しに渡します。しかし、どのように?

私が持っているもの

@Singleton
class JsonOps @Inject() () extends Controller with SecureSocial {...}

ここと私のテストでGlobal.scala説明されているように書かれています...

val controller = new JsonOps
val result = controller.userAwareActionRequestForSomeJson("")(FakeRequest())

次のような電話もあります。

// This is what I would use for production
def extjs = SecuredAction(WithProvider("google")) { implicit request =>
   Ok(views.html.extjs(request.user.firstName))
}
// This is what I would use for testing
def extjs = Action { implicit request =>
  Ok(views.html.extjs("testtesttesting"))
}

この問題が依存性注入に適していると思う理由は何ですか? ただし、使用している Global.scala はジェネリック クラスのインスタンス化子であるため、クラスのインスタンス化をどのように行うかはわかりません。私が持っているコントローラーごとに9000以上の特性を書きたいとは特に思っていません。

大きな間違い

これは UserOpsSpec.scala の 12 行目と 13 行目です。

12  val controller = new UserOps
13  val result = controller.extjs()(FakeRequest())

これがエラーです

[error]     RuntimeException: java.lang.ExceptionInInitializerError (UserOpsSpec.scala:13)
[error] play.api.mvc.ActionBuilder$$anon$1.apply(Action.scala:220)
[error] securesocial.core.SecureSocial$.authenticatorFromRequest(SecureSocial.scala:200)
[error] securesocial.core.SecureSocial$$anonfun$SecuredAction$1.apply(SecureSocial.scala:81)
[error] securesocial.core.SecureSocial$$anonfun$SecuredAction$1.apply(SecureSocial.scala:78)
[error] play.api.mvc.ActionBuilder$$anon$1.apply(Action.scala:215)
[error] play.api.Play$$anonfun$current$1.apply(Play.scala:51)
[error] play.api.Play$$anonfun$current$1.apply(Play.scala:51)
[error] play.api.Play$.current(Play.scala:51)
[error] securesocial.core.Authenticator$.cookieName$lzycompute(Authenticator.scala:188)
[error] securesocial.core.Authenticator$.cookieName(Authenticator.scala:188)
[error] securesocial.core.Authenticator$.<init>(Authenticator.scala:201)
[error] securesocial.core.Authenticator$.<clinit>(Authenticator.scala)
[error] securesocial.core.SecureSocial$.authenticatorFromRequest(SecureSocial.scala:200)
[error] securesocial.core.SecureSocial$$anonfun$SecuredAction$1.apply(SecureSocial.scala:81)
[error] securesocial.core.SecureSocial$$anonfun$SecuredAction$1.apply(SecureSocial.scala:78)
[error] play.api.mvc.ActionBuilder$$anon$1.apply(Action.scala:215)
[error] null
[error] securesocial.core.SecureSocial$.authenticatorFromRequest(SecureSocial.scala:200)
[error] securesocial.core.SecureSocial$$anonfun$SecuredAction$1.apply(SecureSocial.scala:81)
[error] securesocial.core.SecureSocial$$anonfun$SecuredAction$1.apply(SecureSocial.scala:78)
[error] play.api.mvc.ActionBuilder$$anon$1.apply(Action.scala:215)
[error] There is no started application
[error] play.api.Play$$anonfun$current$1.apply(Play.scala:51)
[error] play.api.Play$$anonfun$current$1.apply(Play.scala:51)
[error] play.api.Play$.current(Play.scala:51)
[error] securesocial.core.Authenticator$.cookieName$lzycompute(Authenticator.scala:188)
[error] securesocial.core.Authenticator$.cookieName(Authenticator.scala:188)
[error] securesocial.core.Authenticator$.<init>(Authenticator.scala:201)
[error] securesocial.core.Authenticator$.<clinit>(Authenticator.scala)
[error] securesocial.core.SecureSocial$.authenticatorFromRequest(SecureSocial.scala:200)
[error] securesocial.core.SecureSocial$$anonfun$SecuredAction$1.apply(SecureSocial.scala:81)
[error] securesocial.core.SecureSocial$$anonfun$SecuredAction$1.apply(SecureSocial.scala:78)
[error] play.api.mvc.ActionBuilder$$anon$1.apply(Action.scala:215)
[info]
4

1 に答える 1

2

これが私がこの問題を解決した方法です。メモリ内にある Authenticator に直接追加することで、(一種の) ログインをシミュレートしています。これにより、偽のリクエストに含まれる Cookie が返されます。これは、構文糖衣の暗黙的な変換で行っています。特定のケースに合わせて簡単に拡張できます。私のアプリケーションは user/pass プロバイダーのみを使用していますが、他のプラグインを使用するように拡張できるはずです。

 object TestUtils {

  @inline implicit def loggedInFakeRequestWrapper[T](x: FakeRequest[T]) = new LoggedInFakeRequest(x)

  final class LoggedInFakeRequest[T](val self: FakeRequest[T]) extends AnyVal {
    def withLoggedInUser(id: Long) = {
      val userToLogInAs:Identity = ??? //get this from your database using whatever you have in Global
      val cookie = Authenticator.create(userToLogInAs) match {
        case Right(authenticator) => authenticator.toCookie
      }
      self.withCookies(cookie)
    }
  }        
}

そして仕様:

"render the index page" in {
      val home = route(FakeRequest(GET, "/").withLoggedInUser(1L)).get

      status(home) must equalTo(OK)
      //etc.
    }
于 2013-09-09T00:54:12.150 に答える