Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use gwteventbinder with guice during unit test #17

Open
fedy2 opened this issue Mar 10, 2014 · 7 comments
Open

How to use gwteventbinder with guice during unit test #17

fedy2 opened this issue Mar 10, 2014 · 7 comments

Comments

@fedy2
Copy link

@fedy2 fedy2 commented Mar 10, 2014

This is not an issue but a question.
I've a GWT application that uses GIN and gwteventbinder.
I'm writing some unit tests in order to test the client logic so I'm mocking views and services.
In order to run tests faster I'm avoiding GWTTestCase implementation and trying to run the tests as pure Java. In the test env I'm using directly Guice instead of GIN.
Setting up the tests I've issues providing to Guice a binding for the EventBinders because in normal env this is managed by code generators in GWT.
Have you never faced with the problem?

@gkdn
Copy link
Member

@gkdn gkdn commented Mar 11, 2014

If there is no binding provided for a class, then GIN will create the instance for you via GWT.create. So you can inject your MyEventBinder and then let it automatically handed by GIN.
Then in your test code, you can use Guice and a mocking framework (e.g. mockito) to provide the testing instance for MyEventBinder.

@gkdn
Copy link
Member

@gkdn gkdn commented Mar 11, 2014

@ekuefler: I remember that there was a reflection based implementation for EventBinder. I forgot why we didn't include it as part the open-source release. Do you remember?

@fedy2
Copy link
Author

@fedy2 fedy2 commented Mar 11, 2014

Thank you for your reply @gokdogan.
My idea was to use Mockito to replace the EventBinder implementation but I want to avoid to manually declare all the EventBinders in Guice configuration. The tests are integration tests and they include multiple components that declare an EventBinder.
The only solution that I've in mind is to use reflection in order to discover all the EventBinder extensions and then declare the bindings with a mock implementation in the Guice configuration.

@ekuefler
Copy link
Contributor

@ekuefler ekuefler commented Mar 17, 2014

This is going to be tricky I think. You're basically trying to re-implement GWT.create using Guice. But each EventBinder is its own type and would have to be bound separately. I don't think Guice has any way to say "bind all subtypes of X like this", which is what you would need to get this working without having to explicitly list every EventBinder. It's also going to be hard to figure out reflectively, since Java doesn't have a way to list all subclasses of a given type.

You could probably get this to work using a FakeProvider from GwtMockito - in this case you would keep using GWT.create to create the EventBinder rather than injecting it. GwtMockito works by intercepting calls to GWT.create and allows you to intercept all calls for a supertype, so you could register a FakeProvider for EventBinder that would then be able to instantiate concrete subclasses of it. The implementation would be pretty similar to FakeUiBinderProvider. If you don't want to use GwtMockito you could also set up your own bridge to intercept calls to GWT.create.

I'm not sure if we had a specific reason for not including the reflective EventBinder, would probably be pretty easy to clean up and commit. It's also pretty trivial for people to write themselves.

@tbroyer
Copy link
Contributor

@tbroyer tbroyer commented Mar 17, 2014

This is going to be tricky I think. You're basically trying to re-implement GWT.create using Guice. But each EventBinder is its own type and would have to be bound separately. I don't think Guice has any way to say "bind all subtypes of X like this", which is what you would need to get this working without having to explicitly list every EventBinder.

It should be possible using Guice's SPI. But in the case of a test, I suppose one could live with an explicit binding, provided there's an existing reflective implementation of EventBinder.

@Provides MyEventBinder provideMyEventBinder() {
  return EventBinderSource.create(MyEventBinder.class);
}
@fedy2
Copy link
Author

@fedy2 fedy2 commented Mar 17, 2014

@ekuefler
The FakeProvider from GwtMockito sounds like a nice solution, I will check on it.

@tbroyer
I've searched for a solution using Guice's SPI but with no fortune. Some tests, that are integration tests, involves many EventBinders and I want to a void an explicit binding.

So far I took the "by reflection" solution using the Reflections library (https://github.com/ronmamo/reflections) as support.
The reflections library scans the CP and finds all the EventBinder extensions.
For each extension the target class is analyzed in order to find all the methods to be binded to the event bus (it is the same work done by the EventBinder generator) and a GenericEventHandler is created.
Finally Guice is configured in order to bind the EventBinder extension to a mocked binder.
(Here the used code: https://github.com/cotrix/cotrixrep/blob/master/cotrix/cotrix-web/src/test/java/org/acme/util/EventBinderBindingsProvider.java)

I'm using a similar solution in order to bind the async services interfaces to their effective implementations (We want to run both client and server code in the same JVM), but that is another story.

Thank you all for the support.

@klimeryk
Copy link

@klimeryk klimeryk commented Aug 27, 2014

Hi all,
based on your comments and suggestions, I've come up with the following implementation of a FakeProvider for EventBinder: https://gist.github.com/klimeryk/e090756d9b95dd3bc6aa

It doesn't do much in terms of safe-guarding like checking if the event handler methods have the correct number of arguments, etc. - I'm assuming that EventBinderGenerator/Writer took care of that.
Hopefully this will help someone who stumbled upon this issue :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
5 participants
You can’t perform that action at this time.