djcrankypants / spock

Automatically exported from code.google.com/p/spock
0 stars 0 forks source link

Problem with array arguments to mock methods #294

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
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/PositionalArgument
ListConstraint.java 
b/spock-core/src/main/java/org/spockframework/mock/constraint/PositionalArgument
ListConstraint.java
index 1602cca..3241969 100755
--- 
a/spock-core/src/main/java/org/spockframework/mock/constraint/PositionalArgument
ListConstraint.java
+++ 
b/spock-core/src/main/java/org/spockframework/mock/constraint/PositionalArgument
ListConstraint.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/MockingMethodsWithVa
rArgParameters.groovy 
b/spock-specs/src/test/groovy/org/spockframework/smoke/mock/MockingMethodsWithVa
rArgParameters.groovy
index 079b40e..fb8cce8 100644
--- 
a/spock-specs/src/test/groovy/org/spockframework/smoke/mock/MockingMethodsWithVa
rArgParameters.groovy
+++ 
b/spock-specs/src/test/groovy/org/spockframework/smoke/mock/MockingMethodsWithVa
rArgParameters.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)
   }

Original issue reported on code.google.com by n...@gulmohar.se on 20 Jan 2013 at 10:53

GoogleCodeExporter commented 8 years ago
This is a duplicate of issue 283.

Original comment by n...@gulmohar.se on 29 Jan 2013 at 8:28

GoogleCodeExporter commented 8 years ago
Pulled. Thanks for the excellent patch!

Original comment by pnied...@gmail.com on 30 Mar 2013 at 10:41

GoogleCodeExporter commented 8 years ago
Issue 283 has been merged into this issue.

Original comment by pnied...@gmail.com on 30 Mar 2013 at 10:44

GoogleCodeExporter commented 8 years ago
Is 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?

Original comment by brian.a....@gmail.com on 25 Sep 2013 at 7:57

GoogleCodeExporter commented 8 years ago
You can always use the latest snapshot.

Original comment by pnied...@gmail.com on 26 Sep 2013 at 6:37