Skip to content

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

@AndreasTu

Description

@AndreasTu

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions