Request for advice: Robolectric integration
I want to test some network protocol related parts of our Android app. It depends fairly tightly on Android API components, and I would like to avoid just mocking everything. Over the last couple of days, I've been trying to hack together some lifecycle hooks to do this, but I'm fairly inexperienced with Java and frankly everything is a little bewildering. I've got a LauncherInterceptor modeled after the one in junit5-robolectric-extension, and by logging statements I can tell it's running, however I keep getting:
java.lang.IllegalStateException: No instrumentation registered! Must run under a registering instrumentation.
at androidx.test.platform.app.InstrumentationRegistry.getInstrumentation(InstrumentationRegistry.java:45)
I suspect that this means that I'm not holding the ClassLoader right. However, the reason I'm not posting more detailed code is that I'm confused in a way that makes me doubt I understand the basic concepts involved. Is there an overall strategy for doing this kind of thing that's obvious to someone with more experience? Any guidance would be appreciated.
Thanks in advance, Phillip
Hi @phdavis1027, I'm a bit lost about what you want to do and how that relates to jqwik. Maybe you can provide more context?
Hi @phdavis1027, I'm a bit lost about what you want to do and how that relates to jqwik. Maybe you can provide more context?
Hi! Thanks for the response. Sorry, let me try to be a bit more clear.
Basically, I want to run jqwik tests in a Robolectric sandbox. However, Robolectric has its own classloader etc, which are designed to work with the JUnit4 engine. So I'd have to write my own logic, presumably in the form of jqwik hook implementations, for setting up and tearing down all that logic. It seems that with the Jupiter engine I would write a LauncherInterceptor and an InvocationInterceptor, among some other things. However, I don't see obvious analogues to those extension points in jqwik. Am I missing something, or else approaching this from a totally wrong angle?
Hope that clarifies, Phillip
OK, that makes more sense to me. :-)
I've no idea what Robolectric does but I can talk about the hooks that might be useful in that case:
- LauncherInterceptor is provided by the JUnit platform, so it can be used for all test engines, including jqwik.
- As for InvocationInterceptor, there is no direct equivalent in jqwik, but InvokePropertyMethodHook could be usable instead if you want to use a different class loader for executing the properties. See https://jqwik.net/docs/1.9.3/javadoc/net/jqwik/api/lifecycle/InvokePropertyMethodHook.html
Since I have never used the hooks for swapping in a different class loader there may be some unintended side-effects when you do it. For example, other life cycle methods use a different class loader and do not combine well with the tests and properties. I guess the only way to find that out is by trying :-/
Interesting. After a weekend of reflection, I think I now see the problem as essentially creating a mapping between the RobolectricTestRunner, which handles that classloading stuff, and jqwik lifecycle methods -- from this code it appears that they basically rip out all the logic except what happens at the start of a classBlock, then run all the other setup and teardown logic everytime in each methodBlock's sandbox.
Anyway, thank you for pointing to the InvokePropertyMethodHook, I have a flight this week and will see if I can make something work on the plane