spock icon indicating copy to clipboard operation
spock copied to clipboard

Spock fails with insufficient invocation count when route cause was underneath exception

Open hajdukd opened this issue 7 years ago • 5 comments

Assuming we use groovy and assuming we have such service method:

method(input){ Long val = Optional.ofNullable(input).map(Integer::longValue).orElse(doesntmatter); return otherService.something(val); }

Also assuming we expect that second service Mock will be invoked once (1 * otherService...). When passing Long as "input" parameter i would expect exception:

java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer

But what i get is failed invocation count for otherService shadowing underneath exception.

Removing count check results in correct behaviour - exception being properly handled.

For me it looks like Spock completely ignores underneath exceptions in case of failed invocation count checks.

hajdukd avatar Jun 05 '18 11:06 hajdukd

Please provide a SSCCE and provide the other info that is suggested in the issue template.

This works fine:

class SuppressedExceptions extends Specification {

  def "Mock interaction violations don't hide exceptions"() {
    given:
    List mock = Mock()

    when:
    List foo = 1
    mock.add("foo")

    then:
    1 * mock.add(_)
  }
}

Fails with

org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object '1' with class 'java.lang.Integer' to class 'java.util.List'

	at org.spockframework.smoke.mock.SuppressedExceptions.Mock interaction violations don't hide exceptions(SuppressedExceptions.groovy:12)

leonard84 avatar Jun 30 '18 18:06 leonard84

Ill provide an extensive example. Ps. The redirect does not work.

hajdukd avatar Jul 01 '18 11:07 hajdukd

@hajdukd Correct link is: http://www.sscce.org/ - Short, Self Contained, Correct (Compilable), Example

MartyIX avatar Jul 01 '18 17:07 MartyIX

import spock.lang.*

class Foo {
    def bar
    def baz
   
    void run() {
        int cce = bar
        baz.size()
    }
}

class MyFirstSpec extends Specification {
  def "let's try this!"() {
    given:
    Foo foo = new Foo()
    foo.bar = "not int"
    foo.baz = Mock(List)

    when:
    foo.run()

    then:
    thrown(IllegalArgumentException)
    1 * foo.baz.size()
  }
}
MyFirstSpec
 - let's try this!   FAILED

   Too few invocations for:
   
   1 * foo.baz.size()   (0 invocations)
   
   Unmatched invocations (ordered by similarity):
   
   None
   
   
   at org.spockframework.mock.runtime.InteractionScope.verifyInteractions(InteractionScope.java:78)
   at org.spockframework.mock.runtime.MockController.leaveScope(MockController.java:76)
   at MyFirstSpec.let's try this!(Script1.groovy:23)

Without the cardinality:

    then:
    thrown(IllegalArgumentException)
    foo.baz.size()
MyFirstSpec
 - let's try this!   FAILED

   Expected exception of type 'java.lang.IllegalArgumentException', but got 'org.codehaus.groovy.runtime.typehandling.GroovyCastException'
   at org.spockframework.lang.SpecInternals.checkExceptionThrown(SpecInternals.java:79)
   at org.spockframework.lang.SpecInternals.thrownImpl(SpecInternals.java:66)
   at MyFirstSpec.let's try this!(Script1.groovy:24)
   Caused by: org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'not int' with class 'java.lang.String' to class 'int'
   at Foo.run(Script1.groovy:8)
   at MyFirstSpec.let's try this!(Script1.groovy:21)

FrantaM avatar Sep 21 '18 17:09 FrantaM

Looks like @FrantaM added what you @leonard84 wanned.

hajdukd avatar Sep 21 '18 21:09 hajdukd