spockframework / spockframework/spock

Interactions in when blocks are not preserved if the then block contains an interaction

Open
#1,759 8 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Java
Stars
3.6k
Forks
483
PR merge metrics
No merged PRs in 30d

Description

Describe the bug

Interactions in a when: block are not active after the following then: block, if the then: block contains an interactions,
although the documentation states:

"Interactions declared outside a then: block are active from their declaration until the end of the
containing feature method."

The two features below describe the problem
"When block interaction still active after when block without verification"
"When block interactions are only active during the when block, if verification present"

The single verification line 1 * m.start() in the then: block, changes the behavior of the m.isStarted() method for the rest of the feature execution.

Internals:
If there is a interaction in the then: block, there is a second InteractionScope in the MockController and the interaction in the when: will be added to the top InteractionScope (the second scope from the then:), which will be deactivated by the leaveScope() of the then:. This will drop the interaction from the when: block.

So it does not reflect the behavior stated in the documentation.

Also see the discussion in #1728.

To Reproduce
  def "When block interaction still active after when block without verification"() {
    given:
    def m = Mock(Engine)
    when:
    m.isStarted() >> true
    def result = m.isStarted()
    m.start()
    then:
    m.isStarted()
    result
    when: "Here the isStarted() still reflect the when block above"
    result = m.isStarted()
    then:
    m.isStarted()
    result
  }

  def "When block interactions are only active during the when block, if verification present"() {
    given:
    def m = Mock(Engine)
    when:
    m.isStarted() >> true
    def result = m.isStarted()
    m.start()
    then:
    //If you remove the next line the behavior of isStarted() is different
    1 * m.start()
    !m.isStarted()
    result
    when: "Now the isStarted() does not reflect the when block"
    result = m.isStarted()
    then:
    !m.isStarted()
    !result
  }

  static class Engine {
    private boolean started

    boolean isStarted() { return started }
    void start() { started = true }
    void stop() { started = false }
  }
Expected behavior

The interactions in when block shall be preserved up until the end of the feature method.

Actual behavior

The when: block interactions are dropped after the when: block.

So I would expected that the m.isStarted() >> true holds up until the end of the feature, and should not be affected by the 1 * m.start() in the then: block.

Java version

17.0.8

Buildtool version

Gradle 8.1

Build time: 2023-04-12 12:07:45 UTC
Revision: 40ba32cde9d6daf2b92c39376d2758909dd6b813

Kotlin: 1.8.10
Groovy: 3.0.15
Ant: Apache Ant(TM) version 1.10.11 compiled on July 10 2021
JVM: 17.0.8 (Amazon.com Inc. 17.0.8+7-LTS)
OS: Windows 10 10.0 amd64

What operating system are you using

Windows

Dependencies

Spock-master

Additional context

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the two reproduction feature methods in issue #1759 and trace MockController's InteractionScope handling across when and then blocks. Inspect how leaveScope() deactivates scopes, then add or run regression coverage for interactions declared in when blocks. Done means those interactions remain active through the containing feature method even when a then block contains an interaction.

Written by the indexing model from the issue text.

Assessment

Tech stack
groovy, java
Domain
testing
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.