2013-10-30 62 views
4

讓我問這可能歸結爲一個關於良好的應用設計;-)正確方法

  1. 什麼是使用基於事件通信的最佳實踐兩個耦合的問題在e4 RCP應用程序中?
  2. 如何爲使用依賴注入和IEventBroker發送/接收事件的類編寫簡單的單元測試(使用JUnit)?

讓我們來更具體一點:假設我正在開發一個由多個需要通信的插件組成的Eclipse e4 RCP應用程序。爲了溝通,我想使用org.eclipse.e4.core.services.events.IEventBroker提供的事件服務,這樣我的插件保持鬆散耦合。我使用依賴注入到事件代理注入到調度事件類:

@Inject static IEventBroker broker; 
private void sendEvent() { 
broker.post(MyEventConstants.SOME_EVENT, payload) 
} 

在接收端,我有一個方法,如:

@Inject 
@Optional 
private void receiveEvent(@UIEventTopic(MyEventConstants.SOME_EVENT) Object payload) 

現在的問題:

  1. 爲了IEventBroker被成功注入,我的類需要訪問當前的IEclipseContext。我的大多數使用事件服務的類都沒有被e4應用程序模型引用,所以我必須使用例如手動注入上下文來實例化。 ContextInjectionFactory.inject(myEventSendingObject, context); 這種方法很有效,但我發現自己將很多上下文傳遞到使用事件服務的任何地方。這是否真的是通過E4應用程序進行基於事件的通信的正確方法?

  2. 如何輕鬆地爲使用事件服務的類(無論是作爲發送者還是接收者)編寫JUnit測試?顯然,由於沒有可用的上下文,因此上述註釋都不能單獨使用。我瞭解每個人都相信依賴注入簡化了可測試性。但是,這是否也適用於像IEventBroker這樣的注入服務?

This article描述了創建自己的IEclipseContext以在測試中包含DI的過程。不知道這是否可以解決我的第二個問題,但我也猶豫是否將所有測試作爲JUnit插件測試運行,因爲它似乎不可用於啓動每個單元測試的PDE。也許我只是誤解了這個方法。

This article談到「簡單地嘲弄IEventBroker」。是啊,那樣最好了!不幸的是,我找不到有關如何實現這一目標的任何信息。

所有這些讓我想知道我是否仍然走在正確的軌道上,或者這是否已經是糟糕的設計?如果是這樣,你將如何去重新設計?將所有事件相關的動作移至專用事件發送者/接收者類或專用插件?

+0

Eclipse e4源代碼肯定有很多注入IEventBroker的類。 –

+0

好的,謝謝,看着Eclipse的來源是個好主意。現在我主要擔心測試。任何想法如何IEventBroker可以嘲笑單元測試? –

回答

4

實際上,運行JUnit插件測試並不是那麼昂貴。您可以將啓動配置配置爲在headless mode中運行,因此唯一加載的是沒有工作臺的輕量級PDE。例如在Tycho運行無頭構建時也會發生同樣的情況。 Surefire默認啓動你的測試包作爲無頭插件測試。

與單獨的單元測試相比,您可以訪問插件的資源,最重要的是使用依賴注入。如果要模擬注入的對象,則必須運行插件測試,以便使用InjectorFactory。

這是你將如何去嘲諷事件服務:IEventBroker是一個接口,所以你需要做的唯一事情是寫它

public class IEventBrokerMock implements IEventBroker { 
    @Override 
    // Implemented Methods 
} 

模擬實現在您的測試方法,你能有像

InjectorFactory.getDefault().addBinding(IEventBroker.class).implementedBy(IEventBrokerMock.class); 
ClassUnderTest myObject = InjectorFactory.getDefault().make(ClassUnderTest.class, null); 

如果你想與上下文工作的測試方法反而會包含

IEclipseContext context = EclipseContextFactory.create(); 
context.set(IEventBroker.class, new IEventBrokerMock()); 
ClassUnderTest myObject = ContextInjectionFactory.make(ClassUnderTest.class, context); 

如果您將其作爲JUnit插件測試運行,您的對象將會注入模擬事件服務。

-1

用於測試,而不是DI,我使用「eventBroker = new org.eclipse.e4.ui.services.internal.events.EventBroker();」要獲得一個可以使用的事件處理對象,它可以正常工作