Under certain conditions spock will throw a ClassCastException in PositionalArgumentListConstraint.expandVarargs. The conditions are:
- A method is mocked whose last argument is an array of primitive objects
- The method has an interaction specified
- The method is invoked with a last argument that is an array of primitive objects
- The invocation matches the method signature, but does not match the interaction
This has been observed on Spock 0.7, Groovy 1.8
A spec that exposes the problem and a possible fix is available.
The following changes since commit 3507661e014d54bbbc83ac7e235027fe6324dca2:
JSON demo report (2013-01-18 01:37:46 +0100)
are available in the git repository at:
git://github.com/niligulmohar/spock.git array-arguments
for you to fetch changes up to 337d6b83121f12a38de77a933730b94495c98288:
Fix problem with array arguments to mock methods (2013-01-20 22:59:19 +0100)
Nicklas Lindgren (1): Fix problem with array arguments to mock methods
.../src/main/java/org/spockframework/mock/constraint/PositionalArgumentListConstraint.java | 12 +++++++++++- .../src/test/groovy/org/spockframework/smoke/mock/MockingMethodsWithVarArgParameters.groovy | 14 ++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/spock-core/src/main/java/org/spockframework/mock/constraint/PositionalArgumentListConstraint.java b/spock-core/src/main/java/org/spockframework/mock/constraint/PositionalArgumentListConstraint.java index 1602cca..3241969 100755 --- a/spock-core/src/main/java/org/spockframework/mock/constraint/PositionalArgumentListConstraint.java +++ b/spock-core/src/main/java/org/spockframework/mock/constraint/PositionalArgumentListConstraint.java @@ -16,6 +16,7 @@
package org.spockframework.mock.constraint;
+import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -58,8 +59,17 @@ public class PositionalArgumentListConstraint implements IInvocationConstraint {
private List<Object> expandVarArgs(List<Object> args) { List<Object> expanded = new ArrayList<Object>(); + Object lastArg = CollectionUtil.getLastElement(args); expanded.addAll(args.subList(0, args.size() - 1)); - expanded.addAll(Arrays.asList((Object[]) CollectionUtil.getLastElement(args))); + if (Object[].class.isAssignableFrom(lastArg.getClass())) { + expanded.addAll(Arrays.asList((Object[]) lastArg)); + } else { + int length = Array.getLength(lastArg); + for (int i = 0; i < length; i++) { + Object element = Array.get(lastArg, i); + expanded.add(element); + } + } return expanded; }
diff --git a/spock-specs/src/test/groovy/org/spockframework/smoke/mock/MockingMethodsWithVarArgParameters.groovy b/spock-specs/src/test/groovy/org/spockframework/smoke/mock/MockingMethodsWithVarArgParameters.groovy index 079b40e..fb8cce8 100644 --- a/spock-specs/src/test/groovy/org/spockframework/smoke/mock/MockingMethodsWithVarArgParameters.groovy +++ b/spock-specs/src/test/groovy/org/spockframework/smoke/mock/MockingMethodsWithVarArgParameters.groovy @@ -185,6 +185,16 @@ class MockingMethodsWithVarArgParameters extends Specification { 1 * mock.foo(1, new Object[0]) }
- def "handle matching primitive array value in invocation of a vararg interaction"() {
- def mock = Mock(GroovyPrimitiveArrayParameter) +
- when:
- mock.foo(1, [2, 3] as byte[]) +
- then:
- 1 * mock.foo(1, 2, 3)
} + interface GroovyVarArgParameter { def foo(int i, String... strings) } @@ -193,6 +203,10 @@ class MockingMethodsWithVarArgParameters extends Specification { def foo(int i, String[] strings) }
interface GroovyPrimitiveArrayParameter {
- def foo(int i, byte[] bytes)
- } + interface NoVarArgParameter { def foo(int i, strings) }
Comment #1
Posted on Jan 29, 2013 by Happy GiraffeThis is a duplicate of issue 283.
Comment #2
Posted on Mar 30, 2013 by Grumpy CatPulled. Thanks for the excellent patch!
Comment #3
Posted on Mar 30, 2013 by Grumpy CatIssue 283 has been merged into this issue.
Comment #4
Posted on Sep 25, 2013 by Quick RhinoIs there a timeline for getting a release that contains this? We have a bunch of tests that use this and they won't work with 0.7. Is there a release candidate available?
Comment #5
Posted on Sep 26, 2013 by Grumpy CatYou can always use the latest snapshot.
Status: Fixed
Labels:
Type-Defect
Module-Core
Milestone-1.0