jMock

Can't mock classes in Eclipse JUnit Plugin-Tests

Details

  • Type: Bug Bug
  • Status: Resolved Resolved
  • Priority: Major Major
  • Resolution: Fixed
  • Affects Version/s: 2.1.0
  • Fix Version/s: 2.5.0
  • Component/s: JMock 2.x.x Library
  • Labels:
    None
  • Number of attachments :
    2

Description

Hi Nat,

when I'm mocking classes with the new 2.1 features, I get an exception for eclipse plugin tests.

On the other hand, when using interfaces in the same unit tests then jmock works well both with Eclipse standard JUnit tests as well as with JUnit Plugin-Tests (the plugin tests start the tests in an eclipse instance with the eclipse class loading mechanisms activated)!

This seems to be a problem of the cglib Library, so I'm not sure whether to file a bug report in this project rather than here (the cglib project seems to be not very active)... I also tried easymock and rmock with cglib: the same behavior, an exception with plugin tests and everything ok with simple JUnit tests.

net.sf.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null
at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:237)
at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
at net.sf.cglib.proxy.Enhancer.createClass(Enhancer.java:317)
at org.jmock.lib.legacy.ClassImposteriser.createProxyClass(ClassImposteriser.java:76)
at org.jmock.lib.legacy.ClassImposteriser.imposterise(ClassImposteriser.java:54)
at org.jmock.internal.ReturnDefaultValueAction.invoke(ReturnDefaultValueAction.java:62)
at org.jmock.Mockery.dispatch(Mockery.java:187)
at org.jmock.Mockery.access$000(Mockery.java:34)
at org.jmock.Mockery$MockObject.invoke(Mockery.java:236)
at org.jmock.internal.InvocationDiverter.invoke(InvocationDiverter.java:27)
at org.jmock.internal.ProxiedObjectIdentity.invoke(ProxiedObjectIdentity.java:36)
at org.jmock.lib.legacy.ClassImposteriser$3.invoke(ClassImposteriser.java:85)
at com.avaloq.adt.env.core.model.dbobjects.impl.TaskDBObjectImpl$$EnhancerByCGLIB$$90026834.getChanges(<generated>)
at com.avaloq.adt.env.internal.ui.properties.audit.model.TaskAuditJobTest$2.<init>(TaskAuditJobTest.java:55)
at com.avaloq.adt.env.internal.ui.properties.audit.model.TaskAuditJobTest.testMe(TaskAuditJobTest.java:54)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:128)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.pde.internal.junit.runtime.RemotePluginTestRunner.main(RemotePluginTestRunner.java:58)
at org.eclipse.pde.internal.junit.runtime.CoreTestApplication.run(CoreTestApplication.java:24)
at org.eclipse.core.internal.runtime.PlatformActivator$1.run(PlatformActivator.java:78)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:92)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:68)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:400)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:177)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.eclipse.core.launcher.Main.invokeFramework(Main.java:336)
at org.eclipse.core.launcher.Main.basicRun(Main.java:280)
at org.eclipse.core.launcher.Main.run(Main.java:977)
at org.eclipse.core.launcher.Main.main(Main.java:952)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at net.sf.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:384)
at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:219)
... 46 more
Caused by: java.lang.NullPointerException
at org.jmock.internal.SearchingClassLoader.findClass(SearchingClassLoader.java:54)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
... 52 more

  1. jMock-Testing.txt
    15/Jun/07 3:53 AM
    3 kB
    Ulli Hafner

Issue Links

Activity

Hide
Nat Pryce added a comment -

What is the class-loader structure used to load classes into your plugin tests? Where is the jMock JAR loaded from in this structure? Is jMock loaded from a class loader that can see the mocked type?

It might be that you need to write a new Imposteriser that knows how to load classes from the Eclipse workspace.

Show
Nat Pryce added a comment - What is the class-loader structure used to load classes into your plugin tests? Where is the jMock JAR loaded from in this structure? Is jMock loaded from a class loader that can see the mocked type? It might be that you need to write a new Imposteriser that knows how to load classes from the Eclipse workspace.
Hide
Nat Pryce added a comment -

The SearchingClassLoader should not be throwing null-pointer exceptions. I've checked a fix for that into CVS.

Show
Nat Pryce added a comment - The SearchingClassLoader should not be throwing null-pointer exceptions. I've checked a fix for that into CVS.
Hide
Ulli Hafner added a comment -

Hi Nat,

as far as I understand the eclipse class loading strategies, each plugin uses its own class loader, classes from other plugins are not visible here (for details see
http://www.eclipsezone.com/articles/eclipse-vms/).

E.g., when I have the plugin foo with the class Foo and the plugin foo.test with the class FooTest then these classes are loaded by different class loaders. Only the plugin foo.tests has references to the jmock and cglib library.

Maybe its not possible at all to generate classes dynamically in the eclipse runtime with cglib?

Best regards, Ulli

Show
Ulli Hafner added a comment - Hi Nat, as far as I understand the eclipse class loading strategies, each plugin uses its own class loader, classes from other plugins are not visible here (for details see http://www.eclipsezone.com/articles/eclipse-vms/). E.g., when I have the plugin foo with the class Foo and the plugin foo.test with the class FooTest then these classes are loaded by different class loaders. Only the plugin foo.tests has references to the jmock and cglib library. Maybe its not possible at all to generate classes dynamically in the eclipse runtime with cglib? Best regards, Ulli
Hide
Nat Pryce added a comment -

Is there anything you can do with "buddy" class loaders? Is the foo.test bundle a buddy of the foo bundle? Does that even make a difference? I'm afraid I don't know anything about writing Eclipse plugins.

If you could make the smallest Eclipse project that demonstrates this problem and send attach it as a tar.gz file I could open it in my IDE and trace through what's going on in the jMock classloader.

Show
Nat Pryce added a comment - Is there anything you can do with "buddy" class loaders? Is the foo.test bundle a buddy of the foo bundle? Does that even make a difference? I'm afraid I don't know anything about writing Eclipse plugins. If you could make the smallest Eclipse project that demonstrates this problem and send attach it as a tar.gz file I could open it in my IDE and trace through what's going on in the jMock classloader.
Hide
Ulli Hafner added a comment -

2 Eclipse plugins that expose this behavior. You still need to copy your RC4 jar files to the lib folder of the tests plugin.

The test is quite simple: One class MockMe in the example plugin and a corresponding MockMeTest class in the tests plugin. The first method returns an object of the type MockMe, the second a String. The first test fails , the second works.

Show
Ulli Hafner added a comment - 2 Eclipse plugins that expose this behavior. You still need to copy your RC4 jar files to the lib folder of the tests plugin. The test is quite simple: One class MockMe in the example plugin and a corresponding MockMeTest class in the tests plugin. The first method returns an object of the type MockMe, the second a String. The first test fails , the second works.
Hide
Ulli Hafner added a comment -

Hi Nat,

I just tried the Eclipse buddy policy for this example and the test case runs!

In the example plugin manifest add:
Eclipse-BuddyPolicy: registered

In the tests plugin add:
Eclipse-RegisterBuddy: jmock.example

In my previous attempts I simple interchanged these definitions...

However, my "real" testcase still does not work. This testcase has a lot of dependencies to other plugins. It is hard to find out for which other plugins I need to define this buddy policy (maybe for all my projects?).

It would be nice if you could catch the exception and add additional information, e.g., which class could not be loaded. Then I can add the required buddy policy for the logged classes only.

Thanks, Ulli

Show
Ulli Hafner added a comment - Hi Nat, I just tried the Eclipse buddy policy for this example and the test case runs! In the example plugin manifest add: Eclipse-BuddyPolicy: registered In the tests plugin add: Eclipse-RegisterBuddy: jmock.example In my previous attempts I simple interchanged these definitions... However, my "real" testcase still does not work. This testcase has a lot of dependencies to other plugins. It is hard to find out for which other plugins I need to define this buddy policy (maybe for all my projects?). It would be nice if you could catch the exception and add additional information, e.g., which class could not be loaded. Then I can add the required buddy policy for the logged classes only. Thanks, Ulli
Hide
Nat Pryce added a comment -

I've raised another issue for better reporting of class-loading problems.

Show
Nat Pryce added a comment - I've raised another issue for better reporting of class-loading problems.
Hide
Nat Pryce added a comment -

This would be a great topic for the jMock cookbook. Would you be willing to write up a short HOW-TO document describing how to use jMock with Eclipse plugin tests? I'll be happy to mark that up into HTML and post to the website.

Show
Nat Pryce added a comment - This would be a great topic for the jMock cookbook. Would you be willing to write up a short HOW-TO document describing how to use jMock with Eclipse plugin tests? I'll be happy to mark that up into HTML and post to the website.
Hide
Ulli Hafner added a comment -

Hi Nat,

I'll be happy to provide a Howto. I'm already planning an jmock introduction for our team so I can combine both tasks...

Best regards, Ulli

Show
Ulli Hafner added a comment - Hi Nat, I'll be happy to provide a Howto. I'm already planning an jmock introduction for our team so I can combine both tasks... Best regards, Ulli
Hide
Ulli Hafner added a comment -

Hi Nat,

sorry to bother again, but while writing some examples for our team I found another problem with the eclipse class loader. In my previous test case I mocked a String and the mock class itself which workes as expected. However, when trying to mock a java.lang.List then an exception is thrown again. While it is easy to add the eclipse buddy mechanismn for plugins I really have no clue how to do this for classes provided by the JDK. I added the additional test case in the attached projects.

Note: I tried to use easymock (with class extension), and this mocking framework correctly handles this testcase. Maybe there is still a small bug somewhere?

Exception:
java.lang.IllegalArgumentException: could not imposterise class java.util.ArrayList
at org.jmock.lib.legacy.ClassImposteriser.createProxyClass(ClassImposteriser.java:103)
at org.jmock.lib.legacy.ClassImposteriser.imposterise(ClassImposteriser.java:59)
at org.jmock.internal.ReturnDefaultValueAction.invoke(ReturnDefaultValueAction.java:62)
at org.jmock.Mockery.dispatch(Mockery.java:187)
at org.jmock.Mockery.access$000(Mockery.java:34)
at org.jmock.Mockery$MockObject.invoke(Mockery.java:236)
at org.jmock.internal.InvocationDiverter.invoke(InvocationDiverter.java:27)
at org.jmock.internal.ProxiedObjectIdentity.invoke(ProxiedObjectIdentity.java:36)
at org.jmock.lib.legacy.ClassImposteriser$4.invoke(ClassImposteriser.java:112)
at jmock.example.MockMe$$EnhancerByCGLIB$$f0be7318.createList(<generated>)
at jmock.example.tests.MockMeTest$4.<init>(MockMeTest.java:41)
at jmock.example.tests.MockMeTest.testCreateList(MockMeTest.java:40)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:128)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.pde.internal.junit.runtime.RemotePluginTestRunner.main(RemotePluginTestRunner.java:58)
at org.eclipse.pde.internal.junit.runtime.CoreTestApplication.run(CoreTestApplication.java:24)
at org.eclipse.core.internal.runtime.PlatformActivator$1.run(PlatformActivator.java:78)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:92)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:68)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:400)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:177)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.eclipse.core.launcher.Main.invokeFramework(Main.java:336)
at org.eclipse.core.launcher.Main.basicRun(Main.java:280)
at org.eclipse.core.launcher.Main.run(Main.java:977)
at org.eclipse.core.launcher.Main.main(Main.java:952)
Caused by: net.sf.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null
at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:237)
at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
at net.sf.cglib.proxy.Enhancer.createClass(Enhancer.java:317)
at org.jmock.lib.legacy.ClassImposteriser.createProxyClass(ClassImposteriser.java:97)
... 43 more
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at net.sf.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:384)
at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:219)
... 46 more
Caused by: java.lang.NoClassDefFoundError: net/sf/cglib/proxy/Factory
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
... 52 more

Show
Ulli Hafner added a comment - Hi Nat, sorry to bother again, but while writing some examples for our team I found another problem with the eclipse class loader. In my previous test case I mocked a String and the mock class itself which workes as expected. However, when trying to mock a java.lang.List then an exception is thrown again. While it is easy to add the eclipse buddy mechanismn for plugins I really have no clue how to do this for classes provided by the JDK. I added the additional test case in the attached projects. Note: I tried to use easymock (with class extension), and this mocking framework correctly handles this testcase. Maybe there is still a small bug somewhere? Exception: java.lang.IllegalArgumentException: could not imposterise class java.util.ArrayList at org.jmock.lib.legacy.ClassImposteriser.createProxyClass(ClassImposteriser.java:103) at org.jmock.lib.legacy.ClassImposteriser.imposterise(ClassImposteriser.java:59) at org.jmock.internal.ReturnDefaultValueAction.invoke(ReturnDefaultValueAction.java:62) at org.jmock.Mockery.dispatch(Mockery.java:187) at org.jmock.Mockery.access$000(Mockery.java:34) at org.jmock.Mockery$MockObject.invoke(Mockery.java:236) at org.jmock.internal.InvocationDiverter.invoke(InvocationDiverter.java:27) at org.jmock.internal.ProxiedObjectIdentity.invoke(ProxiedObjectIdentity.java:36) at org.jmock.lib.legacy.ClassImposteriser$4.invoke(ClassImposteriser.java:112) at jmock.example.MockMe$$EnhancerByCGLIB$$f0be7318.createList(<generated>) at jmock.example.tests.MockMeTest$4.<init>(MockMeTest.java:41) at jmock.example.tests.MockMeTest.testCreateList(MockMeTest.java:40) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:585) at junit.framework.TestCase.runTest(TestCase.java:154) at junit.framework.TestCase.runBare(TestCase.java:127) at junit.framework.TestResult$1.protect(TestResult.java:106) at junit.framework.TestResult.runProtected(TestResult.java:124) at junit.framework.TestResult.run(TestResult.java:109) at junit.framework.TestCase.run(TestCase.java:118) at junit.framework.TestSuite.runTest(TestSuite.java:208) at junit.framework.TestSuite.run(TestSuite.java:203) at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:128) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386) at org.eclipse.pde.internal.junit.runtime.RemotePluginTestRunner.main(RemotePluginTestRunner.java:58) at org.eclipse.pde.internal.junit.runtime.CoreTestApplication.run(CoreTestApplication.java:24) at org.eclipse.core.internal.runtime.PlatformActivator$1.run(PlatformActivator.java:78) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:92) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:68) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:400) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:177) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:585) at org.eclipse.core.launcher.Main.invokeFramework(Main.java:336) at org.eclipse.core.launcher.Main.basicRun(Main.java:280) at org.eclipse.core.launcher.Main.run(Main.java:977) at org.eclipse.core.launcher.Main.main(Main.java:952) Caused by: net.sf.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:237) at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377) at net.sf.cglib.proxy.Enhancer.createClass(Enhancer.java:317) at org.jmock.lib.legacy.ClassImposteriser.createProxyClass(ClassImposteriser.java:97) ... 43 more Caused by: java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:585) at net.sf.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:384) at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:219) ... 46 more Caused by: java.lang.NoClassDefFoundError: net/sf/cglib/proxy/Factory at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:620) ... 52 more
Hide
Ulli Hafner added a comment -

Reopened in order to attach the new eclipse project attachment that shows this bug.

Show
Ulli Hafner added a comment - Reopened in order to attach the new eclipse project attachment that shows this bug.
Hide
Ulli Hafner added a comment -

2 Eclipse plugins that expose this bug.

Show
Ulli Hafner added a comment - 2 Eclipse plugins that expose this bug.
Hide
Nat Pryce added a comment -

I can reproduce the problem when I run a plugin test, but not when I run the unit tests normally.

Show
Nat Pryce added a comment - I can reproduce the problem when I run a plugin test, but not when I run the unit tests normally.
Hide
Ulli Hafner added a comment -

Yes, it occurs only for plugin-unit test. Eclipse does not use its classloader "hell" when starting normal unit tests.

When changing all the jmock calls to corresponding easymock calls, then everything works fine? And as far as I know the easymock class extension also works with the cglib class library.

BTW: While debugging this testcases I notices that the 2.1 jars seem to be linked with the wrong sources. When stopping at a breakpoint line the current line was not in sync with source line, I stepped somewhere Iin a JavaDoc comment when I should be in a method body...

Show
Ulli Hafner added a comment - Yes, it occurs only for plugin-unit test. Eclipse does not use its classloader "hell" when starting normal unit tests. When changing all the jmock calls to corresponding easymock calls, then everything works fine? And as far as I know the easymock class extension also works with the cglib class library. BTW: While debugging this testcases I notices that the 2.1 jars seem to be linked with the wrong sources. When stopping at a breakpoint line the current line was not in sync with source line, I stepped somewhere Iin a JavaDoc comment when I should be in a method body...
Hide
Paulo Silveira added a comment -

It seems that eclipse´s plugins classloader does not allow access to sun.* magic classes to bypass the constructors and so on.

Ulli, do you really need a java.util.ArrayList mock? wouldnt java.util.List be enough?

Show
Paulo Silveira added a comment - It seems that eclipse´s plugins classloader does not allow access to sun.* magic classes to bypass the constructors and so on. Ulli, do you really need a java.util.ArrayList mock? wouldnt java.util.List be enough?
Hide
Ulli Hafner added a comment -

Mocking of an ArrayList ist not required, typically my signatures use List<T> as parameter (or return value).

Show
Ulli Hafner added a comment - Mocking of an ArrayList ist not required, typically my signatures use List<T> as parameter (or return value).
Hide
Ulli Hafner added a comment -

HOWTO mock classes in Eclipse plug-ins. Instructions on how to change the Eclipse MANIFEST files to use jMock class mocking.

Show
Ulli Hafner added a comment - HOWTO mock classes in Eclipse plug-ins. Instructions on how to change the Eclipse MANIFEST files to use jMock class mocking.
Hide
Nat Pryce added a comment - - edited

I'm thinking of closing this issue off as a "Won't Fix" because...

1) It only occurs during "in-container" testing, which is not what jMock is really designed for.

2) It can be worked around by writing an Imposteriser that works well with Eclipse's class-loaders and plugging it into the Mockery. It might be possible to write an EclipsePluginClassImposteriser by removing the class-loader hackery from jMock's ClassImposteriser.

3) A custom Imposteriser for Eclipse plug-in testing is a very specific need, and shouldn't go into the jMock core distribution.

Show
Nat Pryce added a comment - - edited I'm thinking of closing this issue off as a "Won't Fix" because... 1) It only occurs during "in-container" testing, which is not what jMock is really designed for. 2) It can be worked around by writing an Imposteriser that works well with Eclipse's class-loaders and plugging it into the Mockery. It might be possible to write an EclipsePluginClassImposteriser by removing the class-loader hackery from jMock's ClassImposteriser. 3) A custom Imposteriser for Eclipse plug-in testing is a very specific need, and shouldn't go into the jMock core distribution.
Hide
Nat Pryce added a comment -

Oops... I meant to comment, not close!

Show
Nat Pryce added a comment - Oops... I meant to comment, not close!
Hide
Ulli Hafner added a comment -

That's ok for me. Seems to be that currently no mocking lib is able to handle this special problem.
The only thing what currently can't be mocked are classes from singed Eclipse projects, and that is not that impoertant since typically I need to mock interfaces only.

See similar bug report (from me): http://code.google.com/p/mockito/issues/detail?id=11

Show
Ulli Hafner added a comment - That's ok for me. Seems to be that currently no mocking lib is able to handle this special problem. The only thing what currently can't be mocked are classes from singed Eclipse projects, and that is not that impoertant since typically I need to mock interfaces only. See similar bug report (from me): http://code.google.com/p/mockito/issues/detail?id=11
Hide
Ulli Hafner added a comment -

Hi Nat, just another input. The guy from mockito fixed the problem recently. Maybe you could re-use his solution for jmock.

See http://code.google.com/p/mockito/issues/detail?id=11&can=1

Show
Ulli Hafner added a comment - Hi Nat, just another input. The guy from mockito fixed the problem recently. Maybe you could re-use his solution for jmock. See http://code.google.com/p/mockito/issues/detail?id=11&can=1
Hide
Nat Pryce added a comment -

Their fix would break jMock's support for Maven Surefire.

Wow, the Mockito guys sure like reinventing the wheel!

Show
Nat Pryce added a comment - Their fix would break jMock's support for Maven Surefire. Wow, the Mockito guys sure like reinventing the wheel!
Hide
Nat Pryce added a comment -

I think I understand the Eclipse plugin class-loader structures now.

When running in a plug-in, jMock does not appear on the system or thread classpaths. So, the classloader used to load jMock's classes has to be added to the searching classloader used by the imposteriser.

I've committed a fix to SVN. I've only been able to test it manually but I can run both JUnit and Plug-in tests with jMock.

Show
Nat Pryce added a comment - I think I understand the Eclipse plugin class-loader structures now. When running in a plug-in, jMock does not appear on the system or thread classpaths. So, the classloader used to load jMock's classes has to be added to the searching classloader used by the imposteriser. I've committed a fix to SVN. I've only been able to test it manually but I can run both JUnit and Plug-in tests with jMock.

People

Vote (0)
Watch (0)

Dates

  • Created:
    Updated:
    Resolved: