Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem with array arguments to mock methods #416

Closed
robfletcher opened this issue Aug 30, 2015 · 5 comments
Closed

Problem with array arguments to mock methods #416

robfletcher opened this issue Aug 30, 2015 · 5 comments

Comments

@robfletcher
Copy link
Contributor

Originally reported on Google Code with ID 294

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)
   }

Reported by nili@gulmohar.se on 2013-01-20 22:53:16

@robfletcher
Copy link
Contributor Author

This is a duplicate of issue 283.

Reported by nili@gulmohar.se on 2013-01-29 20:28:13

@robfletcher
Copy link
Contributor Author

Pulled. Thanks for the excellent patch!

Reported by pniederw on 2013-03-30 22:41:54

  • Status changed: Fixed
  • Labels added: Milestone-1.0

@robfletcher
Copy link
Contributor Author

Issue 283 has been merged into this issue.

Reported by pniederw on 2013-03-30 22:44:34

@robfletcher
Copy link
Contributor Author

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?

Reported by brian.a.kramer on 2013-09-25 19:57:55

@robfletcher
Copy link
Contributor Author

You can always use the latest snapshot.

Reported by pniederw on 2013-09-26 06:37:49

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant