基於從issue在gwteventbinder項目的意見和建議(您報道:)),我想出了下面的代碼:
public class FakeEventBinderProvider implements FakeProvider<EventBinder<?>> {
@Override
public EventBinder<?> getFake(Class<?> type) {
return (EventBinder<?>) Proxy.newProxyInstance(FakeEventBinderProvider.class.getClassLoader(), new Class<?>[] { type }, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, final Object[] args) throws Throwable {
String methodName = method.getName();
assert methodName.equals("bindEventHandlers");
final List<HandlerRegistration> registrations = new LinkedList<HandlerRegistration>();
EventBus eventBus = (EventBus) args[1];
List<Method> presenterMethods = getAllMethods(args[0].getClass());
for (final Method presenterMethod : presenterMethods) {
if (presenterMethod.isAnnotationPresent(EventHandler.class)) {
@SuppressWarnings("unchecked") // Should always be ok, since the Generator for EventBinder should do all the safe-checking
Class<? extends GenericEvent> eventType = (Class<? extends GenericEvent>) (presenterMethod.getParameterTypes())[0];
registrations.add(eventBus.addHandler(GenericEventType.getTypeOf(eventType), new GenericEventHandler() {
@Override
public void handleEvent(GenericEvent event) {
try {
presenterMethod.setAccessible(true);
presenterMethod.invoke(args[0], event);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}
}));
}
}
return new HandlerRegistration() {
@Override
public void removeHandler() {
for (HandlerRegistration registration : registrations) {
registration.removeHandler();
}
registrations.clear();
}
};
}
});
}
private List<Method> getAllMethods(Class<?> type) {
List<Method> methods = new LinkedList<Method>();
methods.addAll(Arrays.asList(type.getDeclaredMethods()));
if (type.getSuperclass() != null) {
methods.addAll(getAllMethods(type.getSuperclass()));
}
return methods;
}
}
至於建議,我已經根據這個在FakeUiBinderProvider
的執行。 這是非常簡單的,一旦你擺脫Java反射克魯夫特的:
- 找到所有被註解爲
@EventHandler
方法。
- 註冊調用指定事件類型的回調方法的新處理程序。
- 返回一個
HandlerRegistration
打電話給removeHandler
刪除所有在前一點添加的處理程序(此行爲是從gwteventbinder的實際實施中複製的)。
請記住,在你的@Before
方法來註冊這個提供者,例如:
@Before
public void setUpEventBindery() {
GwtMockito.useProviderForType(EventBinder.class, new FakeEventBinderProvider());
}
你只需要爲基本接口,EventBinder
做到這一點,因爲作爲GwtMockito.useProviderForType
的文件說:
(..)給定的提供者應該用於GWT.create給定類型的實例,並且的子類。