com.gwtplatform.tester.MockHandlerModule Maven / Gradle / Ivy
/**
* Copyright 2011 ArcBees Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.gwtplatform.tester;
import com.google.inject.AbstractModule;
import com.google.inject.internal.UniqueAnnotations;
import com.gwtplatform.dispatch.client.actionhandler.AbstractClientActionHandler;
import com.gwtplatform.dispatch.client.actionhandler.ClientActionHandler;
import com.gwtplatform.dispatch.rpc.server.actionhandler.ActionHandler;
import com.gwtplatform.dispatch.rpc.shared.Action;
import com.gwtplatform.dispatch.rpc.shared.Result;
/**
* Module for use in test cases when creating a guice injector that needs to
* provide mock handlers.
*
* Your injector must also have an class that subclasses {@link com.gwtplatform.dispatch.server.guice.HandlerModule}
* to bind Actions to ActionHandlers and ActionValidators.
*
* You should subclass this module and use the {@link #configureMockHandlers()}
* method to:
*
* - register mock server-side action handlers with
* {@link #bindMockActionHandler(Class, ActionHandler)}.
* - register mock client-side action handlers with
* {@link #bindMockClientActionHandler(Class, AbstractClientActionHandler)}.
*
*
* Unit Testing Example
*
*
* // create mock handlers
* CreateFooActionHandler mockCreateFooActionHandler =
* mock(CreateFooActionHandler.class);
*
* GeocodeAddressClientActionHandler geocodeAddressClientActionHandler =
* mock(GeocodeAddressClientActionHandler.class);
*
* // create injector
* Injector injector =
* Guice.createInjector(new MyHandlerModule(),
* new MockHandlerModule() {
* {@literal}@Override
* protected void configureMockHandlers() {
* bindMockActionHandler(
* CreateFooActionHandler.class,
* mockCreateFooActionHandler);
* }
* bindMockClientActionHandler(
* GeocodeAddressAction.class,
* geocodeAddressClientActionHandler);
* });
*
* // get dispatcher
* DispatchAsync dispatcher = injector.getInstance(DispatchAsync.class);
*
* // create mock result
* final CreateFooResult result =
* new CreateFooResult(new Key(Foo.class, 1));
*
* // configure mockito to return mock result on specific action
* when(
* businessCreateActionHandler.execute(
* eq(new CreateFooAction("Bar")),
* any(ExecutionContext.class))).thenReturn(result);
*
* // configuring mockito to return result for clent action handler
* // is a bit more complex
* final GeocodeAddressResult geocodeAddressResult = new GeocodeAddressResult(...);
* doAnswer(new Answer<Object>() {
* {@literal @SuppressWarnings("unchecked")}
* public Object answer(InvocationOnMock invocation) {
* AsyncCallback<GeocodeAddressResult> callback
* = (AsyncCallback<GeocodeAddressResult>) invocation.getArguments()[1];
* callback.onSuccess(new GeocodeAddressResult(geocodeAddressResult));
* return null;
* }
* }).when(geocodeAddressClientActionHandler)
* .execute(
* eq(new GeocodeAddressAction("2 Google Way, New Zealand",
* "nz")), any(AsyncCallback.class),
* any(ClientDispatchRequest.class), any(ExecuteCommand.class));
*
*
*
* @author Brendan Doherty
*/
public abstract class MockHandlerModule extends AbstractModule {
private static class MockClientActionHandlerMapImpl, R extends Result>
implements MockClientActionHandlerMap {
private final Class actionClass;
private final ClientActionHandler clientActionHandler;
public MockClientActionHandlerMapImpl(final Class actionClass,
final ClientActionHandler clientActionHandler) {
this.actionClass = actionClass;
this.clientActionHandler = clientActionHandler;
}
@Override
public Class getActionClass() {
return actionClass;
}
@Override
public ClientActionHandler getClientActionHandler() {
return clientActionHandler;
}
}
@Override
protected void configure() {
install(new TestDispatchModule());
configureMockHandlers();
}
protected abstract void configureMockHandlers();
/**
* Use bindMockActionHandler instead.
*/
@Deprecated
protected , R extends Result, H extends ActionHandler> void bindMockHandler(
Class handler, H mockHandler) {
bindMockActionHandler(handler, mockHandler);
}
/**
* Registers a mock server-side action handlers.
*
* This mock server-side action handler will be executed when the class under
* test calls {@link com.gwtplatform.dispatch.shared.DispatchAsync#execute
* DispatchAsync#execute()} or
* {@link com.gwtplatform.dispatch.shared.DispatchAsync#undo
* DispatchAsync#undo()}.
*
* @param Type of {@link Action} that will be executed by mock handler
* @param Type of {@link Result} that will be returned by mock handler
* @param Type of the mock handler that extends
* {@link ActionHandler}
* @param handlerClass The type of the mock server-side handler
* @param mockHandler Instance of the {@link ActionHandler} to execute
* actions of type {@literal }
*/
protected , R extends Result, H extends ActionHandler> void bindMockActionHandler(
Class handlerClass, H mockHandler) {
bind(handlerClass).toProvider(new MockProvider(mockHandler));
}
/**
* Registers a mock client-side action handlers.
*
* This mock client-side action handler will be executed when the class under
* test calls {@link com.gwtplatform.dispatch.shared.DispatchAsync#execute
* DispatchAsync#execute()} or
* {@link com.gwtplatform.dispatch.shared.DispatchAsync#undo
* DispatchAsync#undo()}.
*
*
* If both mock client and mock server action handlers have been registered,
* the server side action handler will only be called if the mock client side
* action handler calls
* {@link com.gwtplatform.dispatch.client.actionhandler.ExecuteCommand#execute
* ExecuteCommand#execute()} or
* {@link com.gwtplatform.dispatch.client.actionhandler.UndoCommand#undo
* UndoCommand#undo()}
*
* @param Type of {@link Action}
* @param Type of {@link Result}
* @param Type of {@link AbstractClientActionHandler}
* @param actionClass Implementation of {@link ActionHandler} to link
* and bind
* @param mockHandler Instance of the {@link ActionHandler} to execute
* actions of type {@literal }
*/
protected , R extends Result, H extends AbstractClientActionHandler> void bindMockClientActionHandler(
Class actionClass, H mockHandler) {
bind(MockClientActionHandlerMap.class).annotatedWith(
UniqueAnnotations.create()).toInstance(
new MockClientActionHandlerMapImpl(actionClass, mockHandler));
}
}