微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

模拟适用于 Android 的 AWS Amplify Auth API

如何解决模拟适用于 Android 的 AWS Amplify Auth API

我的 Android 应用程序使用 AWS Cognito 和 Amplify Auth SDK 进行身份验证,我正在尝试为登录/注册流程编写 JUnit 测试用例。我正在使用 Mockito 框架来模拟这些类。

我从登录开始,我的登录模型是这样的

class LoginService(val auth: AuthCategory) {

 fun login(username: String,password: String): mutablelivedata<Login> {
    val liveData = mutablelivedata<Login>()
    auth.signIn(username,password,{ result ->
            liveData.postValue(Login(result,null))
        },{ error ->
            liveData.postValue(Login(null,error))
        }
    )
    return liveData
    }
  }

我的视图模型是这样调用

class Loginviewmodel : viewmodel() {

    val loginService = LoginService(Amplify.Auth)

    fun login(username: String,password: String): mutablelivedata<Login> {
        return loginService.login(username,password)
    }
}

我的测试用例是这样的

lateinit var auth: AuthCategory
lateinit var loginService: LoginService

@Before
fun onSetup() {
    auth = mock(Amplify.Auth::class.java)
    loginService = LoginService(auth)
}

@Test
fun logintest() {
    val authSignIn: Consumer<*>? = mock(Consumer::class.java)
    val authEx: Consumer<*> = mock(Consumer::class.java)
    `when`(
        auth.signIn(
            anyString(),anyString(),authSignIn as Consumer<AuthSignInResult>,authEx as Consumer<AuthException>
        )
    )
    loginService.login("username","password").observeForever {
        assertTrue(it.result?.isSignInComplete!!)
    }
}

请帮我验证这个方法, 我正在尝试找出一种方法来触发 AuthSignInResult 方法AuthExceptionAuth.signIn(),以便在登录成功或出现错误时断言。

我对 AWS Amplify 和 Cognito 环境非常陌生,非常感谢以正确方式执行此操作的建议/参考。提前致谢。

解决方法

您可以通过多种方式通过 Amplify Android 提高可测试性。在以下两种方法中,我肯定会从第一种方法开始。

使用类别接口

这是一种“单元测试”级别的方法。

Amplify.Auth 实现了 AuthCategoryBehavior 接口。因此,如果您更改所有代码以使用该接口,则只需模拟它即可。

假设您有一些使用 Auth 作为依赖项的类:

class YourClass(private val auth: AuthCategoryBehavior = Amplify.Auth) {
    ...
}

现在,在您的生产代码中,您的依赖注入代码将执行以下操作:

  1. 初始化放大(使用 addPlugin(AWSCognitoAuthPlugin())Ampify.configure(...) 等)
  2. 接下来,返回一个由 YourClass 构建的单例 YourClass(auth = Amplify.Auth)

但是,在您的测试代码中,您可以使用 Amplify Auth 内容的模拟构建 YourClass 的实例:

val mockAuth = mock(AuthCategoryBehavior::class.java)
val yourClass = YourClass(mockAuth)

通过它,您可以指定它在测试条件下的行为方式:

doAnswer
    { invocation ->
        // Get a handle to the success callback
        val onResult =
            invocation.arguments[2] as Consumer<AuthSignInResult>
        // Invoke it with some canned result
        onResult.accept(mock(AuthSignInResult::class.java))
    }
    .`when`(mockAuth)
    .signIn(eq(username),eq(password),any(),any())

使用 OkHttp 的 MockWebServer

这更像是一种“组件”或“集成”级别的方法。在这里,我们将使用 MockWebServer 实例从假 Cognito 服务器返回预设响应。

在此流程中,您将在生产和测试中使用所有真实的 Amplify 库代码。只要相信您可以控制 Cognito 对客户的响应。

为此,您应该在 Android Studio 的网络监视器选项卡中查看实际 HTTP 响应。然后,将该内容安排到下面的测试代码中。

val mockWebServer = MockWebServer()
mockWebServer.start(8080);
val fakeCognitoEndpointUrl = mockWebServer.url("/");

val cookedResponse = new MockResponse()
    .setResponseCode(200)
    .setBody(new JSONObject()
        .put("blah blah","content you saw in Network Monitor")
        .toString()
    )
mockWebServer.enqueue(cookedResponse)

// Build up a JSON representation of your `amplifyconfiguration.json`
// But replace the endpoint URL with mock web server's.
val json = JSONObject()
    .put(...)
    // Find correct field to populate by
    // viewing structure of amplifyconfiguration.json
    .put("Endpoint",fakeCognitoEndpointUrl)

val config = AmplifyConfiguration.fromJson(json)
Amplify.addPlugin(AWSCognitoAuthPlugin())
Amplfiy.configure(config,context)
val yourClass = YouClass(auth = Amplify.Auth)

在第二个示例中未指定一些细节,但希望这足以让您找到工作方向。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。