最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

kotlin - How do I write unit tests to ensure that a function fails and retries a few times before succeeding? - Stack Overflow

programmeradmin0浏览0评论

I have a function that looks like this:

fun runWorkflow(data: Promise<Data>) {
    withRetries(data, data.get().timeout) {
        runAction(it.get(), client)
    }
}

runWorkflow is in its own file and is not part of a class. withRetries is a function from an external library, it will rerun the inner block repeatedly until data.get().timeout minutes have expired. client is a static import.

This is runAction (it is in a separate file, and is also not part of a class):

internal fun runAction(data: Data, client: Client): Promise<Data> {
   doSomethingWithClientOrData()
   return somethingElse()
}

I need to test that when runWorkflowis called, it does so with retries. I couldn't mock or verify the call to withRetries itself.

I figured that I could simulate the retry behavior by mocking the call to runAction, and making it fail a few times before succeeding after N runs. Then I would verify that runWorkflow returns successfully. But this behavior would appear the exact same as runAction only being called once, and succeeding on that call.

I am unsure of what kind of test would enforce that runWorkflow is being called with retries, or how to mock the call to runWorkflow.

I have a function that looks like this:

fun runWorkflow(data: Promise<Data>) {
    withRetries(data, data.get().timeout) {
        runAction(it.get(), client)
    }
}

runWorkflow is in its own file and is not part of a class. withRetries is a function from an external library, it will rerun the inner block repeatedly until data.get().timeout minutes have expired. client is a static import.

This is runAction (it is in a separate file, and is also not part of a class):

internal fun runAction(data: Data, client: Client): Promise<Data> {
   doSomethingWithClientOrData()
   return somethingElse()
}

I need to test that when runWorkflowis called, it does so with retries. I couldn't mock or verify the call to withRetries itself.

I figured that I could simulate the retry behavior by mocking the call to runAction, and making it fail a few times before succeeding after N runs. Then I would verify that runWorkflow returns successfully. But this behavior would appear the exact same as runAction only being called once, and succeeding on that call.

I am unsure of what kind of test would enforce that runWorkflow is being called with retries, or how to mock the call to runWorkflow.

Share Improve this question asked Feb 2 at 23:50 Kevin2566Kevin2566 45110 silver badges23 bronze badges 2
  • Assuming you can have runAction fail in a controlled way, you can assert that runWorkflow() returns successfully and it takes at least the expected time to do so. – David Soroko Commented Feb 3 at 7:00
  • Remember that there are other test doubles other than mocks. Maybe the problem is that client is a static in there and cannot be replaced by a fake, dummy or stub. – Augusto Commented Feb 4 at 15:39
Add a comment  | 

1 Answer 1

Reset to default 0

Assuming that you are using mockk: There you can set up a sequence of responses when something is called. You could, for example set up a mock to fail twice, then succeed.

@Test
fun retryTest() {
  every { something.runAction(any(), any()) } returnsMany responseList
  ...
}

Or, if you need the call to runAction to throw, then use answers and write a specific function that behaves differently on each call:

  every { something.runAction(any(), any()) } answers {
    ...
  }
  ...

This allows for more flexibility.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论