gpt4 book ai didi

java - 如何在单元测试期间将 gwteventbinder 与 guice 一起使用

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:05:30 27 4
gpt4 key购买 nike

我在纯 Java 中执行 GWT 应用程序的单元测试,直接使用 Guice for DI 而不是 GIN(用于正常执行)。我还使用 GWTEventBinder 库 ( https://github.com/google/gwteventbinder ) 作为事件声明和监听的支持库。

根据库的要求,我为每个监听事件的类声明了一个 EventBinder。在正常执行期间,binder 的实例由 GIN 注入(inject)。

但是在单元测试期间,实例应该由 Guice 生成。关于如何让 Guice 生成 EventBinder 实例的任何想法?

最佳答案

根据 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 反射问题,它就非常简单了:

  1. 找到所有用@EventHandler注释的方法。
  2. 注册一个新的处理程序,为指定的事件类型调用回调方法。
  3. 返回一个 HandlerRegistration,它在调用 removeHandler 时删除了上一点添加的所有处理程序(此行为是从 gwteventbinder 的实际实现中复制的)。

记得注册这个提供者,例如在你的@Before 方法中:

@Before
public void setUpEventBindery() {
GwtMockito.useProviderForType(EventBinder.class, new FakeEventBinderProvider());
}

您只需要为基本接口(interface) EventBinder 执行此操作,因为正如 GwtMockito.useProviderForType 的文档所述:

(..) the given provider should be used to GWT.create instances of the given type and its subclasses.

关于java - 如何在单元测试期间将 gwteventbinder 与 guice 一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22250907/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com