spockframework / spockframework/spock

Mocking in given block is ignored when mocked in setup method

Open
#962 14 comments 15 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

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

Description

Issue description

Currently you can declare a certain mocked behaviour in the setup method, which will then be used for every test in the class. If you want to override that behaviour you HAVE to put it in the then block. This is very confusing to people as it is not the natural flow they would describe the test

How to reproduce

groovy example of a test
interface MyInterface {
    int myMethod()

}

class MyInterfaceTest extends Specification {
    def myInterface = Mock(MyInterface)

    def setup() {
        myInterface.myMethod() >> 1
    }

    def "testing regular behaviour"() {
        when:
         def result = myInterface.myMethod()
        then:
         result == 1
     }

    def "testing exceptional behaviour"() {
        given:
         myInterface.myMethod() >> 2
        when:
         def result = myInterface.myMethod()
        then:
         result == 2
      } 
}
Tests in words:
myMethod should always return 1

testing regular behaviour
When myMethod is called
Then the result is 1

testing exceptional behaviour
Given myMethod returns 2
When I call myMethod
Then the result is 2

In this case the second test will fail
You would have to write something like

    def "testing exceptional behaviour"() {
        when:
         def result = myInterface.myMethod()
        then:
         _ * myInterface.myMethod() >> 2
         result == 2
      } 

In words:

When I call myMethod
Then any call of myMethod returns 2
and the result is 2

To me the first wording of the test is a natural flow in comparison to the second version.
So my proposal is to add the given block to override the declarations of the setup-Method.

It is Important though, that the then-Block should still always win as you need to verify how often methods are called as well.

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 supplied MyInterfaceTest reproduction and trace how mock declarations from setup, given, and then blocks are ordered. Add regression coverage showing that given overrides setup while then retains priority, and verify both regular and exceptional examples pass.

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
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.