Twitter、Facebook などへの接続を担当する Social オブジェクトがあり、指定されたユーザーのプロバイダー情報を取得します
プロバイダーごとに、シングルトン TwitterAdapter を実装し、すべて抽象クラス SocialAdapter から継承します。
コードは次のとおりです: https://github.com/RestOpenGov/ideas-ba/blob/master/webservice/app/services/security/SocialConnector.scala#L98
テストのために、Twitter に接続する代わりに固定応答を返すように、明らかに TwitterAdapter をモックしたいと思います。
私が見つけた 1 つの解決策は、暗黙的なパラメーターを使用してアダプターのリストを挿入することでした。このソリューションの問題は、Social.retrieveSocialProviderInfo が他の関数から呼び出されることです。そのため、次のように、すべての呼び出しチェーンを通じて暗黙の List[SocialAdapter] パラメーターを渡す必要があります。
def createApplicationToken(accessToken: AccessToken)
(implicit adapters: List[SocialAdapter] = Social.defaultAdapters)
: Either[List[Error], ApplicationToken] = {
// go to social info provider and fetch information
retrieveProviderInfo(accessToken).fold(
[...]
def retrieveProviderInfo(accessToken: AccessToken)
(implicit adapters: List[SocialAdapter] = Social.defaultAdapters)
: Either[List[Error], IdentityProviderInfo] = {
[...]
そして最後に
object Social {
val defaultAdapters = List(TwitterAdapter, FacebookAdapter)
def retrieveSocialProviderInfo
(accessToken: AccessToken)
(implicit adapters: List[SocialAdapter] = Social.defaultAdapters) // adapters can be injected
: Option[IdentityProviderInfo] = {
[...]
あなたはアイデアを得る
それは正常に動作します。通常、パラメーターの 2 番目のグループを無視し、Social.defaultAdapters からデフォルトを選択します。テスト時に List(MockTwitterAdapter, MockFacebookAdapter) に設定するだけですが、テストできるようにするためだけにコードを乱雑にしています。 .
もう 1 つの解決策は、Social.defaultAdapters を (val ではなく) var にして、テスト用に変更することです。通常、プロダクション モードでは常に同じ値になります。
これはかなり一般的なシナリオでなければならないと思います。これらの状況を処理するためのより良い戦略はありますか? それとも、暗黙の代入の範囲を拡張する何らかの方法でしょうか? それとも、フル機能の依存性注入フレームワークを使用しますか?