admin管理员组

文章数量:1418099

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.

本文标签: