1

我正在尝试使用协程来处理我的登录服务的异步代码。不幸的是,登录服务的实现必须在完成时接受回调。login()在这些回调之一发生之前​​,我不希望此函数完成。

这是我所拥有的:

fun login(): Outcome = runBlocking {
    suspendCoroutine<Outcome> { continuation ->
        loginService.login(
                onLoginSuccess = {
                    // do some stuff
                    continuation.resume(Outcome.SUCCESS)
                },
                onLoginFailure = {
                    // handle failure case
                    continuation.resume(Outcome.FAILURE)
                }
        )
    }
}

我的问题是我的测试永远不会完成。我认为正在发生的事情是延续块本身没有运行。我也尝试将调用包装uut.login()在 runBlocking 中,但没有帮助。这是我的测试代码(使用 Spek):

describe("when login") {

    val successCaptor: ArgumentCaptor<() -> Unit> = TestHelpers.argumentCaptorForClass()
    val failureCaptor: ArgumentCaptor<() -> Unit> = TestHelpers.argumentCaptorForClass()

    var result: Outcome? = null

    beforeEachTest {
        doNothing().whenever(mockLoginService)?.login(capture(successCaptor), capture(failureCaptor))
        result = uut?.execute()
    }

    it("logs in with the login service") {
        verify(mockLoginService)?.login(any(), any())
    }

    describe("and the login succeeds") {

        beforeEachTest {
            successCaptor.value.invoke()
        }

        // other tests...

        it("returns an outcome of SUCCESS") {
            expect(result).to.equal(Outcome.SUCCESS)
        }
    }

    describe("and the login fails") {
        beforeEachTest {
            failureCaptor.value.invoke()
        }

        // other tests...

        it("returns an outcome of FAILURE") {
            expect(result).to.equal(Outcome.FAILURE)
        }
    }
}

基本上,我想断言该login()方法根据发生的情况返回了 SUCCESS 或 FAILURE 结果。

有任何想法吗?

4

1 回答 1

0

当然,我是在发帖后才发现这一点的。如果有兴趣,这是我在测试中所做的:

describe("when login") {

    val successCaptor: ArgumentCaptor<() -> Unit> = TestHelpers.argumentCaptorForClass()
    val failureCaptor: ArgumentCaptor<() -> Unit> = TestHelpers.argumentCaptorForClass()

    var result: Outcome? = null

    describe("and the login succeeds") {

        beforeEachTest {
            whenever(mockLoginService?.login(capture(successCaptor), capture(failureCaptor))).thenAnswer {
                successCaptor.value.invoke()
            }
            result = uut?.execute()
        }

        it("logs in with the login service") {
            verify(mockLoginService)?.login(any(), any())
        }

        it("returns an outcome of SUCCESS") {
            expect(result).to.equal(Outcome.SUCCESS)
        }
    }

    describe("and the login fails") {
        beforeEachTest {
            whenever(mockLoginService?.login(capture(successCaptor), capture(failureCaptor))).thenAnswer {
                failureCaptor.value.invoke()
            }
            result = uut?.execute()
        }

        it("logs in with the login service") {
            verify(mockLoginService)?.login(any(), any())
        }

        // other tests

        it("returns an outcome of FAILURE") {
            expect(result).to.equal(Outcome.FAILURE)
        }
    }
}
于 2018-05-07T19:01:58.117 回答