[ https://issues.apache.org/jira/browse/GROOVY-4843?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Paul King closed GROOVY-4843. ----------------------------- > Mocking a method with byte[] parameter type throws a ClassCastException: > ArrayList cannot be cast to Number > ----------------------------------------------------------------------------------------------------------- > > Key: GROOVY-4843 > URL: https://issues.apache.org/jira/browse/GROOVY-4843 > Project: Groovy > Issue Type: Bug > Components: mocks and stubs > Affects Versions: 1.7.10, 1.8.0 > Reporter: Sébastien Launay > Assignee: Eric Milles > Priority: Major > Fix For: 5.0.0-beta-1, 3.0.25, 4.0.27 > > Attachments: GROOVY-fix-mock-byte-array-method-2011-05-25.patch > > > If I want to mock a class with a method having a single byte[] paremeter like > this one: > {code:java} > 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 > {code} > it will fail with the following exception: > {noformat} > 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) > {noformat} > This is because {{MockInterceptor}} invoke the target closure by expanding > the arguments array like this: > {code:java} > return result(*arguments) > {code} > 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): > {noformat} > Object[] {byte[]} => Object[] {Object[] {ArrayList<Byte>}} => byte[] > {noformat} > instead of the excepted coercion: > {noformat} > Object[] {byte[]} => Object[] {Byte[]} => byte[] > {noformat} > 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. -- This message was sent by Atlassian Jira (v8.20.10#820010)