Mocking fails for generic classes with NoSuchMethodException on $Proxy objects #210

Closed
hamid-nazari opened this Issue Sep 27, 2015 · 0 comments

Projects

None yet

2 participants

@hamid-nazari

I recently updated JMockit from 1.16 to 1.19 and ran all test suites I had prepared for my previously reported issues and all passed correctly.
But yesterday one of my developers reported a failure on her old tests cases which used to pass. Wondering what might have went wrong, I finally restored JMockit 1.16 to find out that the test pass now.
This was very weird exception to spot and it was very hard to reproduce in another test case. I had to work on it for few hours before being able to create such combination with simplified version of our complex hierarchy of generic objects.

I also check with other versions and found out that the issue manifests itself from update 1.17 onward.

Here is the test case

import static org.testng.Assert.assertEquals;

import org.testng.annotations.Test;

import mockit.Injectable;
import mockit.NonStrictExpectations;

public class JMockitGenericsFailureTests
{
    public interface Identifier
    {
    }

    public static class ModuleID implements Identifier
    {
        public static final ModuleID    ID1 = new ModuleID();
        public static final ModuleID    ID2 = new ModuleID();
        public static final ModuleID    ID3 = new ModuleID();
    }

    public interface Identifiable<ID_TYPE extends Identifier>
    {
        ID_TYPE getID();
    }

    public interface IRegistrar<SUB_ITEM_TYPE extends Identifiable<ID_TYPE>, ID_TYPE extends Identifier>
    {
        SUB_ITEM_TYPE getSubItem(ID_TYPE subItemID);
    }

    public interface IModule extends Identifiable<ModuleID>
    {

    }

    public interface IApplicationStub<UTILITY_TYPE extends Identifiable<ModuleID>>
    {
        IRegistrar<UTILITY_TYPE, ModuleID> getModuleRegistry();
    }

    public interface IModularApplication extends IApplicationStub<IModule>
    {

    }

    @Injectable
    private IModularApplication application;

    private IModule testModule1;
    private IModule testModule2;

    @Test
    public void genericsFailure_proxy_NoSuchMethod()
    {
        testModule1 = new IModule()
        {

            @Override
            public ModuleID getID()
            {
                return ModuleID.ID1;
            }
        };

        new NonStrictExpectations()
        {
            {
                application.getModuleRegistry().getSubItem(ModuleID.ID1);
                result = testModule1;
                application.getModuleRegistry().getSubItem(ModuleID.ID2);
                result = testModule2;
                application.getModuleRegistry().getSubItem(ModuleID.ID3);
                result = null;
            }
        }.toString();

        assertEquals(application.getModuleRegistry().getSubItem(ModuleID.ID1), testModule1);
        assertEquals(application.getModuleRegistry().getSubItem(ModuleID.ID2), testModule2);
    }
}

Here is the exception stack trace of running it with 1.17+:

java.lang.RuntimeException: java.lang.InstantiationException: com.sun.proxy.$Proxy6
    at JMockitGenericsFailureTests$2.<init>(JMockitGenericsFailureTests.java:72)
    at JMockitGenericsFailureTests.genericsFailure_proxy_NoSuchMethod(JMockitGenericsFailureTests.java:67)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:497)
Caused by: java.lang.InstantiationException: com.sun.proxy.$Proxy6
    at java.lang.Class.newInstance(Class.java:427)
    ... 4 more
Caused by: java.lang.NoSuchMethodException: com.sun.proxy.$Proxy6.<init>()
    at java.lang.Class.getConstructor0(Class.java:3082)
    at java.lang.Class.newInstance(Class.java:412)
    ... 4 more

Our test environment:

  • JDK 1.8u60
  • TestNG 6.9.5 on Eclipse
  • JMockit 1.16, 1.17, 1.18 and 1.19
@rliesenfeld rliesenfeld added the bug label Sep 28, 2015
@rliesenfeld rliesenfeld self-assigned this Sep 28, 2015
@rliesenfeld rliesenfeld added a commit that closed this issue Sep 30, 2015
@rliesenfeld rliesenfeld Fixed a cascading bug where a proxy class generated from a TypeVariab…
…le was being incorrectly instantiated with the no-args constructor; closes #210.
9d9a32b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment