jira.codehaus.org

  • Log In Access more options
    • Online Help
    • Keyboard Shortcuts
    • About JIRA
    • JIRA Credits
    • What?s New
  • Dashboards Access more options (Alt+d)
  • Projects Access more options (Alt+p)
  • Issues Access more options (Alt+i)
  • groovy
  • GROOVY-4843

Mocking a method with byte[] parameter type throws a ClassCastException: ArrayList cannot be cast to Number

  • Log In
  • Views
    • XML
    • Word
    • Printable

Details

  • Type: Bug Bug
  • Status: Open Open
  • Priority: Major Major
  • Resolution: Unresolved
  • Affects Version/s: 1.7.10, 1.8.0
  • Fix Version/s: None
  • Component/s: mocks and stubs
  • Labels:
    None
  • Testcase included:
    yes
  • Patch Submitted:
    Yes

Description

If I want to mock a class with a method having a single byte[] paremeter like this one:

def baisContext = new MockFor(FileInputStream)
baisContext.demand.read(1..1) {byte[] b ->
  ...
}
def bais = baisContext.proxyDelegateInstance("/dev/null")
bais.read(new byte[2]) // will throws ClassCastException

it will fail with the following exception:

java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.lang.Number
  at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.convertToByteArray(DefaultTypeTransformation.java:701)
  at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.convertToPrimitiveArray(DefaultTypeTransformation.java:802)
  at org.codehaus.groovy.reflection.stdclasses.ArrayCachedClass.coerceArgument(ArrayCachedClass.java:38)
  at org.codehaus.groovy.reflection.ParameterTypes.coerceArgumentsToClasses(ParameterTypes.java:138)
  at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:231)
  at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:272)
  at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:884)
  at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:39)
  at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:42)
  at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:54)
  at groovy.mock.interceptor.MockInterceptor.beforeInvoke(MockInterceptor.groovy:33)
  at groovy.mock.interceptor.MockProxyMetaClass.invokeMethod(MockProxyMetaClass.java:78)
  at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:39)
  at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:42)
  at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
  at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)

This is because MockInterceptor invoke the target closure by expanding the arguments array like this:

return result(*arguments)

resulting in the following type coercion from ParameterTypes#coerceArgumentsToClasses(Object[]) (closure with 1 argument of array type is considered as a variable argument method call):

Object[] {byte[]} => Object[] {Object[] {ArrayList<Byte>}} => byte[]

instead of the excepted coercion:

Object[] {byte[]} => Object[] {Byte[]} => byte[]

I think this issue does not only affects byte[] arguments but most certainly all the kind of arrays.

Current workaround is to use the type List<Byte> instead of byte[] in the closure intercepting the call.

I attached a test case to reproduce the bug plus a proposed fix by using InvokerHelper.invokeClosure() instead of expanding the arguments array.

  • Options
    • Sort By Name
    • Sort By Date
    • Ascending
    • Descending
    • Download All

Attachments

  1. Text File
    GROOVY-fix-mock-byte-array-method-2011-05-25.patch
    24/May/11 5:56 PM
    2 kB
    Sebastien Launay

Activity

  • All
  • Comments
  • Work Log
  • History
  • Activity
There are no comments yet on this issue.

People

  • Assignee:
    Unassigned
    Reporter:
    Sebastien Launay
Vote (0)
Watch (0)

Dates

  • Created:
    24/May/11 5:56 PM
    Updated:
    24/May/11 5:56 PM
  • Atlassian JIRA (v5.0.4#731-sha1:3aa7374)
  • Report a problem
  • Powered by a free Atlassian JIRA open source license for Codehaus. Try JIRA - bug tracking software for your team.