Open fedy2 opened 10 years ago
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.
@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?
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.
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.
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);
}
@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.
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 :)
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?