osgi:install_OSGi服务测试助手:ServiceRegistrationRule

osgi:install

OSGi服务测试可以是避免与悬挂的服务引用有关的问题的有效方法。 就像我在写简单服务贡献验证中所承诺的那样,这次我引入了一个JUnit规则 ,该规则有助于测试组件之间的交互。

OSGi服务测试组件交互

假设我们有一个服务,该服务通知根据whiteboard-pattern绑定的相关观察者。 就像上一篇文章中一样,我们ServiceImpl有一个Service声明和ServiceImpl 。 另外,我们支持ServiceListener ,应在特定操作时通知此服务。

为了表示这样的动作,我们使用名为Service#execute()的方法声明来扩展示例的服务接口:

public interface Service {void execute();
}

除了实现此execute方法之外,贡献类还必须提供绑定和取消绑定ServiceListener引用的功能:

public class ServiceImplimplements Service
{public void execute() {[...]}public void bind( ServiceListener listener ) {[...]}public void unbind( ServiceListener listener ) {[...]}
}

作为通知目的地,回调类型ServiceListener提供了一个称为ServiceListener#executed()的方法声明:

public interface ServiceListener {void executed();
}

要完成设置,我们必须注册服务组件,我们将通过声明式服务再次进行此操作。 请注意附加的0..n参考声明:

<?xml version="1.0" encoding="UTF-8"?>
<scr:componentxmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0"immediate="true" name="Implementation of Service API"><implementation class="com.codeaffine.example.core.ServiceImpl"/><service<<provide interface="com.codeaffine.example.api.Service"/></service><reference bind="bind" unbind="unbind"cardinality="0..n"interface="com.codeaffine.example.api.ServiceListener"name="ServiceListener"policy="dynamic" />
</scr:component>

现在的问题是:我们如何测试侦听器的取消绑定是否正确工作以及按预期方式分发通知? 基本思想是注册一个ServiceListener 间谍并在实际的服务实现上触发Service#execute

间谍记录了要execute调用,并允许验证绑定和通知是否按预期工作。 一旦确定了这一点,我们就可以继续进行注册并注销主要注册的间谍,并验证是否没有收到有关后续操作事件的通知。 这样可以确保解除绑定也按计划进行。

但是,这种情况下的测试夹具通常需要一点OSGi样板。 为了减少混乱,我编写了一个小的JUnit规则,该规则可以简化服务注册并在每次测试运行后自动执行服务注册表清理。

服务注册规则

与其他所有JUnit TestRule ,必须在我们的PDE测试 TestRule ServiceRegistrationRule作为公共字段提供。 注意给定测试用例的类实例,规则如何使用参数化的构造函数。 此引用用于获取适当的BundleContext用于服务注销/注册。

@Rule
public final ServiceRegistrationRule serviceRegistration= new ServiceRegistrationRule( getClass() );private ServiceListener listener;
private Service service;@Before
public void setUp() {service = collectServices( Service.class, ServiceImpl.class ).get( 0 );listener = mock( ServiceListener.class );
}

隐式测试设置使用我在上 ServiceCollector介绍的ServiceCollector检索正在测试的注册服务 。 使用mockito将侦听器DOC创建为间谍。 上述第一个测试方案如下所示:

@Test
public void executeNotification() {serviceRegistration.register( ServiceListener.class, listener );service.execute();verify( listener ).executed();
}

很简单,不是吗?

请注意, ServiceRegistrationRule负责清理并从服务注册表中删除间谍服务。 为了便于测试解除绑定的情况,规则的register方法返回服务注册的句柄:

@Test
public void executeAfterListenerRemoval() {Registration registration= serviceRegistration.register( ServiceListener.class, listener );registration.unregister();service.execute();verify( listener, never() ).executed();
}

第五行( registration.unregister() )从服务注册表中删除侦听器间谍。 这将触发解除绑定,并且永远不会调用侦听器。 当然,现实世界中的场景可以为多个侦听器注册,异常处理等添加其他测试,但是我认为这个概念已经明确了。

结论

到目前为止, ServiceRegistrationRule在我们当前的项目中证明了自己的作用。 它大大减少了样板,使测试更清洁并提高了可读性。 该类是Xiliary P2存储库的com.codeaffine.osgi.test.util功能的一部分: http ://fappel.github.io/xiliary

如果您想查看代码或提出问题,也可以查看Xiliary GitHub项目: https : //github.com/fappel/xiliary

对于其他所有内容,请随时使用下面的评论部分。 在后续文章中,我将说明如何使用集成的PDE-Tes​​ts来设置Maven-tycho构建。 这有点棘手,因为tycho不允许访问当前React堆构建的束,因此请继续关注。

翻译自: https://www.javacodegeeks.com/2015/02/osgi-service-test-helper-serviceregistrationrule.html

osgi:install

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/338143.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言——结构体链表,附完整示例

引用自身的结构体&#xff0c;一个结构体中有一个或多个成员的基类型就是本结构体类型时&#xff0c;说明这个结构体可以引用自己&#xff0c;所以称作引用自身的结构体。例如下面的结构体&#xff1a;struct link{ char ch; struct link *p} a;p是一个可以指向struct link类型…

android 注解点击事件,android click事件注解

定义注解&#xff1a;package com.fyfeng.android.annotations;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;Retention(value RetentionPolicy.RUNTIME…

jax-rs jax-ws_快速浏览JAX-RS请求与方法匹配

jax-rs jax-ws在本文中&#xff0c;我们来看一下JAX-RS中与资源方法匹配的HTTP请求 。 它是JAX-RS的最基本功能之一。 通常&#xff0c;使用JAX-RS API的开发人员不会接触&#xff08;或真正不需要知道&#xff09; 匹配过程的细节&#xff0c;请放心&#xff0c;由于我们的RES…

C语言知识总结——宏,枚举

1、define宏定义以#号开头的都是编译预处理指令&#xff0c;它们不是C语言的成分&#xff0c;但是C程序离不开它们&#xff0c;#define用来定义一个宏&#xff0c;程序在预处理阶段将用define定义的来内容进行了替换。因此在程序运行时&#xff0c;常量表中并没有用define定义的…

C语言知识总结——共用体

union 共用体&#xff08;联合体&#xff09;在进行某些算法的C语言编程的时候&#xff0c;需要使几种不同类型的变量存放到同一段内存单元中。也就是使用覆盖技术&#xff0c;几个变量互相覆盖。这种几个不同的变量共同占用一段内存的结构&#xff0c;在C语言中 以关键字union…

jboss入门_JBoss Forge NetBeans集成–入门

jboss入门JBoss Forge是构建基于Maven的Java EE项目的最快方法。 因此&#xff0c;它已经具有了令人敬畏的功能&#xff0c;使您作为开发人员的生活更加轻松。 在大多数情况下&#xff0c;使用Forge的人们可能会对创建Web应用程序感兴趣。 有很多方法可以开始使用Forge基础知识…

这几道 C/C 题涉及你的知识盲区?

8个C语言面试题&#xff0c;涉及指针、运算、函数、内存&#xff0c;看看你能做出几个&#xff01;1.gets()函数问&#xff1a;请找出下面代码里的问题&#xff1a;#include int main(void) {char buff[10];memset(buff, 0, sizeof(buff));gets(buff); //gets不检查输入的字符…

logback redis_使用Spring Boot和Logback登录到Redis

logback redis在进行集中式日志记录时&#xff0c;例如使用Elasticsearch&#xff0c;Logstash和Kibana或Graylog2&#xff0c;您可以为Java应用程序提供多个选项。 您既可以编写标准的应用程序日志&#xff0c;也可以使用Logstash解析这些日志&#xff0c;这些日志既可以直接使…

荣耀6plus+android5.1,荣耀66Plus EMUI3.0开发版5.5.1版本发布说明

本帖最后由 秀姬 于 2015-6-8 11:22 编辑EMUI 3.0_Android4.4_5.5.1版本发布说明(开发版)适配机型&#xff1a;荣耀6 / 荣耀6 Plus 全系列机型下载地址&#xff1a;荣耀6标配版支持荣耀6手机全系列机型&#xff0c;不区分制式&#xff01;标配版支持L0X的各机型升级&#xff0c…

C 与 C 的真正区别在哪里?

C 与 C 的真正区别在哪里&#xff1f;C是中餐厨师的菜刀&#xff0c;做啥菜就那一把刀&#xff0c;切菜切肉切鱼&#xff0c;都是这一把刀&#xff0c;刀工好的师傅&#xff0c;豆腐都能切成一朵花。无论你提什么概念&#xff0c;都能用指针给你做出来&#xff0c;如果不行&…

byteman_Byteman –用于字节码操纵的瑞士军刀

byteman我正在与JBoss中的许多社区一起工作&#xff0c;有很多有趣的事情要谈论&#xff0c;以至于我无法将自己的每一分都缠住。 这就是为什么我非常感谢有机会不时地欢迎客座博客的主要原因。 今天是Jochen Mader&#xff0c;他是以代码为中心的书呆子群的一部分。 他目前花费…

html 怎么置顶表格,表格(Table)表头固定,内容上滚【5个实例】

当表格往上滚动的时候&#xff0c;表头固定不动&#xff0c;这样可以让用户时刻看清每一列的数据含义&#xff0c;这是人性化的设计&#xff0c;充分考虑了用户使用体验。本文将通过5个实例&#xff0c;来介绍这种表格设计。用户可通过下载源码&#xff0c;直接应用于自己的项目…

C语言变量的定义包括变量存储类型和变量的什么?

C语言变量的定义包括变量存储类型和变量的名称。C语言定义变量的格式&#xff1a;“数据类型 变量名;”&#xff0c;“数据类型”表示想要存储什么类型的数据&#xff0c;“变量名”就是你想给这个变量起个什么名字&#xff0c;通常都是用字母。变量的定义定义变量的格式非常简…

java 调用祖父方法_在Java中调用祖父母方法:您不能

java 调用祖父方法在文章保护的重点中&#xff0c;我详细介绍了“受保护”如何扩展“包私有”访问。 我在那儿写道&#xff1a; 你能做的是 覆盖子类中的方法或 使用关键字super调用parent方法。 通常&#xff0c;这实际上是您可以使用受保护的方法完成的所有操作。 &…

C语言代码注释必须用/**/ , 你没看错~

事情是这样的&#xff0c;有人离职&#xff0c;公司调我补缺。那个系统一直有个工程师在维护&#xff0c;参与该系统的新人来了又走&#xff0c;他始终泰然自若。刚过去一个礼拜&#xff0c;我就心下窃吼&#xff1a;“坑爹啊!”&#xff0c;也彻底体会到什么叫---绝对的权威、…

java8 streams_另一个Java 8 Lamdbas和Streams示例

java8 streams我一直落后于Java 8所关注的功能&#xff0c;因此在这篇文章中&#xff0c;我将简要介绍我对lambda和stream的初步经验。 和往常一样&#xff0c;我将专注于Podcast课程&#xff1a; package org.codingpedia.learning.java.core;import java.util.Comparator;p…

html文档的基本类型,HTML(网页的文档类型介绍)

一个html文件的第一行代码通常就是用于声明网页文档类型&#xff0c;其格式是:这一行不是属于标签文档类型:可以理解为不同的html版本&#xff01;html4.0 或4.01版本基本固定&#xff0c;但又有分化:严格性:了用的标签和属性相对较少&#xff0c;但能兼容更多的浏览器。宽松型…

C语言源代码展示:常用转换函数实现原理

编程时经常用到进制转换、字符转换。比如软件界面输入的数字字符串&#xff0c;如何将字符串处理成数字呢&#xff1f;和大家分享一下。01字符串转十六进制代码实现&#xff1a;void StrToHex(char *pbDest, char *pbSrc, int nLen) {char h1,h2;char s1,s2;int i;for (i0; i …

jax-rs jax-ws_在JAX-RS中处理异步请求中的超时

jax-rs jax-wsJAX-RS 2.0在客户端和服务器端都支持异步编程范例。 这篇文章重点介绍了使用JAX-RS&#xff08;2.0&#xff09;API在服务器端执行异步REST请求时的超时功能 无需过多介绍&#xff0c;这里是一个快速概述。 为了以异步方式执行方法&#xff0c;您只需 需要指定A…

html5 移动 优化,第四天:HTML5移动站优化技巧 摘自《10天学会移动站SEO》

现在大家基本上做手机网站都是做成HTML5的&#xff0c;因为现在智能手机等移动设备越来越多&#xff0c;几乎全部支持HTML5&#xff0c;那么给网站适配上HTML5的网站就很是必要了。以前的WML网站已经淘汰&#xff0c;而最新的方式就这种最好。我们这一节就重点讲一讲HTML5移动网…