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 应用程序模型引用,因此我必须使用 eg 在实例化时手动注入上下文ContextInjectionFactory.inject(myEventSendingObject, context); 这种方法有效,但我发现自己将大量上下文传递到我使用事件服务的任何地方。这真的是跨 E4 应用程序进行基于事件的通信的正确方法吗?

  2. 如何轻松为使用事件服务(作为发送方或接收方)的类编写 JUnit 测试?显然,由于没有可用的上下文,上述注释都不能单独工作。我理解每个人都相信依赖注入简化了可测试性。但这也适用于像 IEventBroker 这样的注入服务吗?

本文描述了创建您自己的 IEclipseContext 以在测试中包含 DI 的过程。不确定这是否可以解决我的第二个问题,但我也犹豫将所有测试作为 JUnit 插件测试运行,因为为每个单元测试启动 PDE 似乎是不切实际的。也许我只是误解了这种方法。

这篇文章讲的是“简单地模拟 IEventBroker”。是啊,那样最好了!不幸的是,我找不到任何关于如何实现这一点的信息。

这一切让我想知道我是否仍然在正确的轨道上,或者这是否已经是一个糟糕的设计案例?如果是这样,您将如何进行重新设计?将所有与事件相关的操作移动到专用的事件发送器/接收器类或专用插件?

4

2 回答 2

4

实际上,运行 JUnit 插件测试并没有那么昂贵。您可以将启动配置配置为在无头模式下运行,因此唯一加载的是没有工作台的轻量级 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 插件测试运行,您的对象将注入模拟事件服务。

于 2013-11-01T21:14:07.860 回答
-1

为了测试,我使用“eventBroker=new org.eclipse.e4.ui.services.internal.events.EventBroker();”而不是 DI 要使用 eventbroker 对象,它可以正常工作

于 2017-02-15T09:51:55.053 回答