hub4j/github-api

Unable to mock GHObject#id

Haarolean opened this issue · 10 comments

Hi,

it seems like it's impossible to mock GHObject via Mockito, I observe this behavior:

try {
    var a = Mockito.mock(GHObject.class);
    when(a.getId()).thenReturn(123L);
} catch (Throwable e) {
    e.printStackTrace();
}

The exception:

java.lang.NullPointerException: Cannot invoke "java.lang.Long.longValue()" because the return value of "java.util.concurrent.Callable.call()" is null
	at org.kohsuke.github.GHObject.getId(GHObject.java:140)
	at org.kohsuke.github.GHObject.getId(GHObject.java:140)

I believe this may be related to bridge methods, but I have no idea how to implement a workaround.

Could you please elaborate if this is possible?

Seems related: mockito/mockito#701

gsmet commented

We had the issue with the Quarkus GitHub API extension + Mockito when we developed Quarkus GitHub App and Quarkus GitHub Action and we couldn't find any good workaround. Mockito and/or ByteBuddy randomly choose one of the method and you end up with flaky tests.

Our solution in this context has been to drop the bridge methods from the bytecode using some Quarkus build time magic. They are only intended for binary compatibility and in a Quarkus environment, people would have to rebuild their app after an upgrade anyway.

But obviously, this cannot be applied in all environments. In other words, you are not alone :).

@gsmet thanks for the feedback, that's very unfortunate.

There are so many issues due to this back-compatibility thing firing back, that the whole experience of using this library reminds me of the "jumping on a rake" meme.
/rant

mockito/mockito#701 was closed a while ago.

@gsmet
I wish you'd filed an issue for this a while ago. It might be possible to publish a no-bridge flavor of the project as part of the release. This version would not guaranteed binary backward compatibility, but maybe that's acceptable for your scenarios. Instead of you having to remove the code, it just wouldn't be there.

I'm working on publishing a github-api-unbridged artifact that doesn't include bridge methods.
https://github.com/hub4j/github-api/tree/release/v1.x-unbridged

However, I haven't gotten it to work yet. https://github.com/hub4j/github-api/actions/runs/6968301386

@bitwiseman let me know if I could help with fixing that

@Haarolean @gsmet
github-api-unbridged v1.318 has been published. We need some additional infrastructure improvements, but you should be able to use this version the same as you would github-api.

https://github.com/hub4j/github-api/actions/runs/6987836071

Thank you very much, it works!

@bitwiseman should we close this?

@Haarolean
Great! We need to note this in the documentation and/or Readme so others will know it exists and what its limitations are (backwards compatibility not guaranteed).

Sure, I'll raise a PR then