簡體   English   中英

如何在單元測試中使用gwteventbinder和guice

[英]How to use gwteventbinder with guice during unit test

我在普通Java中使用Guice for DI而不是GIN(在正常執行中使用)執行GWT應用程序的單元測試。 我還使用GWTEventBinder庫( https://github.com/google/gwteventbinder )作為事件聲明和監聽的支持庫。

根據庫的要求,我為每個聽取事件的類聲明了一個EventBinder。 在正常執行期間,綁定器的實例由GIN注入。

但是在單元測試期間,實例應該由Guice生成。 關於如何讓Guice生成EventBinder實例的任何想法?

根據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 Reflection cruft,它就非常簡單了:

  1. 找到使用@EventHandler注釋的所有方法。
  2. 注冊一個新的處理程序,該處理程序調用指定事件類型的回調方法。
  3. 返回一個HandlerRegistration ,在調用removeHandler會刪除上一點中添加的所有處理程序(此行為是從gwteventbinder的實際實現中復制的)。

請記住注冊此提供程序,例如在@Before方法中:

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

你只需要為基本接口做到這一點, EventBinder ,因為作為文檔GwtMockito.useProviderForType說:

(..)給定的提供者應該用於GWT.create給定類型及其子類的實例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM