spockframework / spockframework/spock
Mock/Spy interaction verification withing specific time frame (with timeout)
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 3.6k
- Forks
- 483
- PR merge metrics
- No merged PRs in 30d
Description
Is your feature request related to a problem?
Testing asynchronous code (schedules, Kafka/RabbitMQ), an expected interaction might be triggered with some delay (e.g. 60ms). The regular verification construction fails immediately and an artificial wait before it is required (or some other hacks workarounds), what reduces the readability.
Describe the solution you'd like
An ability to define optional timeout to wait for an interaction before failing the assertion. E.g.
then:
1.withTimeout(50) * orderFacadeMock.confirmOrder(ORDER_NUMBER)
(1.._).withTimeout(Duration.ofSeconds(1)) * orderFacadeMock.getOrderStatus(_)
Describe alternatives you've considered
As a workaround, I've been usually using some (thread safe) boolean or counter in the stubbing, to verify the number of interactions. However, it makes code less readable and suppress the "Unmatched invocations" reporting.
Recently @Vampire proposed a nicer variant of that approach with CountDownLatch, which eliminates the second limitation, but still requires extra elements and obscures the code.
given:
...
OrderFacade orderFacadeMock = Mock()
def latch = new CountDownLatch(EXPECTED_NUMBER_OF_ORDER_CONFIRMATIONS)
when:
kafkaTemplate(ORDER_CONFIRMED_TOPIC_NAME, ORDER_NUMBER)
then:
latch.await(1000, SECONDS) || true
then:
//orderConfirmed() should be called when Kafka consumer received a message from a designed topic
EXPECTED_NUMBER_OF_ORDER_CONFIRMATIONS * orderFacadeMock.orderConfirmed(ORDER_NUMBER) >> { latch.countDown() }
Additional context
- I didn't check if the DSL modification (to add
withTimeout()to a number of range) can be applied only within the scope of the mock assertion (not to every number "everywhere"). - I don't know, if there isn't any obstacles in the internal implementation of the interaction verification (e.g. that it is moved to the end of the
whenblock. - In Mockito it would be
verify(orderFacadeMock, timeout(200)).orderConfirmed(ORDER_NUMBER).
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
No files or tests are named. Start by tracing Spock's interaction-verification DSL and its timing within the when block, then define focused asynchronous tests for the proposed timeout forms and confirm they preserve unmatched-invocation reporting.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- groovy, java
- Domain
- testing
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100