google / gwtmockito

Better GWT unit testing
https://google.github.io/gwtmockito
Apache License 2.0
157 stars 50 forks source link

Unable to run tests with GwtMockitoTestRunner in IDEA #57

Closed tazle closed 8 years ago

tazle commented 8 years ago

See latest comments on #5 for one possible resolution.

It would be nice to get a release of either the current master or something that directly incorporates context classloader instead of system classloader into the class lookup mechanism.

ekuefler commented 8 years ago

So to be clear, your proposed resolution is to replace getParentClassloader in GwtMockitoTestRunner so that it returns Thread.currentThread().getContextClassLoader() instead of ClassLoader.getSystemClassLoader()?

This seems to me like it's probably the right thing to do; I'm trying to think if it might have any negative side effects. If I understand correctly, IDEA's test runner presumably works by starting a thread, setting that thread's context classloader to something magical, then executing the test on that thread. By having the parent classloader be the system classloader, we're basically bypassing whatever IDEA had set.

In most cases the context classloader will be the same as the system classloader, but in the cases where it's not it's because some tool quite explicitly wanted to use a different classloader for that thread. So it's always going to be better to respect that preference than to force the system classloader.

Does that reasoning sound correct? If so and no one objects I'll make the change. If this is blocking you, you can create your own subclass of GwtMockitoTestRunner that overrides the parent classloader in the meantime.

Thanks for tracking down the problem, these classloader bugs are always super tricky.

tazle commented 8 years ago

Yes, what I did for the version I'm now using in IDEA and with plain Maven is exactly as you described.

And yes, the reasoning sounds correct as well. If you are not interested in resources tied to a particular class, the thread context classloader is always the best bet.

I thought creating a custom subclass would not be all that simple in 1.1.5, but looking at it again now, it seems I might be mistaken. I'll probably try that on Monday.

Edit: Tried to work around this by subclassing in 1.1.5. Overriding getParentClassloader() isn't enough, since the parent class loder isn't explicitly added to the classpath of the ClassPool in 1.1.5. master or 1.1.6 fixes this.

tbroyer commented 8 years ago

If I understand correctly, IDEA's test runner presumably works by starting a thread, setting that thread's context classloader to something magical, then executing the test on that thread.

Or more likely just setting the current thread's context classloader to some kind of URLClassLoader to simply isolate your project's classpath from IDEA test runner's one. Maven uses some similar techniques under certain conditions so it can happen there too: https://maven.apache.org/surefire/maven-surefire-plugin/examples/class-loading.html

ekuefler commented 8 years ago

Alright, I've made the change and pushed a new snapshot to Maven. Been a while since the last release, so I'll release 1.1.6 in a week or so if no one reports any problems

tazle commented 8 years ago

Still no 1.1.6 release.

ekuefler commented 8 years ago

Apologies for the long delay. 1.1.6 has been released and should now be available on Maven Central.