简体   繁体   English

Mocking AWS Amplify Auth APIs for Android

[英]Mocking AWS Amplify Auth APIs for Android

My Android application uses AWS Cognito and Amplify Auth SDK for authentication and I'm trying to write JUnit test cases for login/signup flows.我的 Android 应用程序使用AWS Cognito 和 Amplify Auth SDK进行身份验证,我正在尝试为登录/注册流程编写 JUnit 测试用例。 I'm using Mockito framework to mock the classes.我正在使用 Mockito 框架来模拟这些类。

I started with login, my login model looks like this我从登录开始,我的登录 model 看起来像这样

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

And my viewmodel calls it this way我的视图模型这样称呼它

class LoginViewModel : ViewModel() {

    val loginService = LoginService(Amplify.Auth)

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

And my test case looks like this我的测试用例看起来像这样

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!!)
    }
}

Please help me validate this approach, I'm trying to find out a way to trigger AuthSignInResult and AuthException of Auth.signIn() method so that I would assert if signin is successful or there is an error.请帮助我验证这种方法,我正在尝试找到一种方法来触发 Auth.signIn Auth.signIn()方法的AuthSignInResultAuthException ,以便我断言登录是否成功或有错误。

I'm very new to AWS Amplify and Cognito environment, A suggestion/reference to do this in correct way would be highly appreciated.我对 AWS Amplify 和 Cognito 环境非常陌生,非常感谢以正确方式执行此操作的建议/参考。 Thanks in advance.提前致谢。

There are a couple ways you can encourage testability with Amplify Android.您可以通过多种方式使用 Amplify Android 来鼓励可测试性。 Of the two below, I would definitely start with the first approach.在下面的两个中,我肯定会从第一种方法开始。

Use the category interfaces使用类别接口

This is a "unit test" level approach.这是一种“单元测试”级别的方法。

Amplify.Auth implements the AuthCategoryBehavior interface. Amplify.Auth实现了AuthCategoryBehavior接口。 So, if you change all of your code to use that interface, you can just mock it.因此,如果您更改所有代码以使用该接口,则可以模拟它。

Say you have some class which uses Auth as a dependency:假设您有一些 class 使用 Auth 作为依赖项:

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

Now, in your production code, you'd have your Dependency Injection code do something like this:现在,在您的生产代码中,您将让您的依赖注入代码执行以下操作:

  1. Initialize Amplify (with addPlugin(AWSCognitoAuthPlugin()) , Ampify.configure(...) , etc.)初始化 Amplify(使用addPlugin(AWSCognitoAuthPlugin())Ampify.configure(...)等)
  2. Next, return a singleton your YourClass , built from YourClass(auth = Amplify.Auth)接下来,返回一个 singleton 您的YourClass ,由YourClass(auth = Amplify.Auth)

However in your test code , you can build an instance of YourClass using a mock of the Amplify Auth stuff:但是,在您的测试代码中,您可以使用 Amplify Auth 的模拟来构建YourClass的实例:

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

With that, you can specify how it should behave under test conditions:有了它,您可以指定它在测试条件下的行为方式:

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

Use OkHttp's MockWebServer使用 OkHttp 的MockWebServer

This is more of a "component" or "integration" level approach.这更像是一种“组件”或“集成”级别的方法。 Here, we'll use a MockWebServer instance to return canned responses from a fake Cognito server.在这里,我们将使用MockWebServer实例从假的 Cognito 服务器返回预设响应。

In this flow, you're using all of the real Amplify library code, in both production and in test.在此流程中,您将在生产和测试中使用所有真正的 Amplify 库代码。 Just making believe you can control Cognito's responses to the client.只是让人相信你可以控制 Cognito 对客户的回应。

To do this, you should view the actual HTTP responses in your Android Studio's Network Monitor tab.为此,您应该在 Android Studio 的网络监视器选项卡中查看实际的 HTTP 响应。 Then, arrange that content into the test code below.然后,将该内容安排到下面的测试代码中。

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)

Have left a few details unspecified in this second example, but hopefully it's enough to set you in a working direction.在第二个示例中留下了一些未指定的细节,但希望它足以让您确定工作方向。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Android 应用程序中的 AWS Amplify Cognito 身份验证错误 - AWS Amplify Cognito Auth error in Android app 如何使用 AWS Amplify Android 强制刷新身份验证令牌? - How to force auth token refresh with AWS Amplify Android? AWS Amplify 在 Android 6 上崩溃 - AWS Amplify Crashes on Android 6 AWS 放大 &amp; Android - AWS Amplify & Android AWS Cognito 规则无法匹配使用 aws amplify (Android) 的嵌入式身份验证 UI - AWS Cognito rules can't match the drop-in auth UI using aws amplify (Android) Android AWS Amplify.Auth.signUp() / AWSMobileClient.getInstance().signUp() 对于错误案例有相同的错误代码 - Android AWS Amplify.Auth.signUp() / AWSMobileClient.getInstance().signUp() have same errorCodes for error cases 通过 Android APK 部署时,AWS Amplify Flutter 的身份验证注册功能不起作用 - AWS Amplify Flutter's auth signup function is not working when deployed via Android APK 放大身份验证事件在 android 中不起作用 - Amplify Auth events don't work in android AWS Amplify Auth - 获取已登录用户的用户属性时出错 - AWS Amplify Auth - Error when fetching user attributes of a signed in user 适用于 Android 的 AWS Amplify - 无法解析符号“AmplifyModelProvider” - AWS Amplify for Android - Cannot resolve symbol 'AmplifyModelProvider'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM