我在DS中编写了一个@component,它应该在多个实例中实例化并激活。为了测试我已经写了一个pax考试测试我在哪里启动karaf并添加了scr。一切正常,但是......在测试方法运行之前它不会实例化服务,因此没有空间去做断言等。
@Test
public final void testing() throws Exception {
props = createProperties(user, pass, host);
cfg = configurationAdmin.
createFactoryConfiguration(CouchbaseConnectionProvider.SVC_NAME);
cfg.update(props);
final ServiceTracker tracker = new ServiceTracker(bundleContext, CouchbaseConnectionProvider.class, null);
tracker.open();
CouchbaseConnectionProvider svc = (CouchbaseConnectionProvider) tracker.waitForService(5000);
// It will wait 5s and after testing exits it will create the service
}
我在这里做错了什么? 因为当方法退出时,它将正确地创建和激活具有所有属性的服务。
我可以使用线程“ion(3)-127.0.0.1”添加测试方法,当DS实例化时使用线程“84-b6b23468b652”。
干杯, 马里奥
更新3 实际上有两个错误,一个在我身边,一个在其他地方(在felix CM?),因为配置可以通过我的界面访问impl bundle一段时间后(当容器关闭时)但它应该真的绑定到pax测试当容器关闭时,捆绑(当然还有CM本身)并且永远不会“自由:d”。哪个bug我不知道 - 我将结束一个简约的mvn项目并尝试felix cm的人,我会在这里发布更新。
更新2 如果有人有兴趣跟进进度(如果有错误的话)我已经提交了一个错误(https://ops4j1.jira.com/browse/PAXEXAM-725)。)
更新1 这是我在testclass中的配置
package se.crossbreed.foundation.persistence.provider.couchbase;
@RunWith(PaxExam.class)
@ExamReactorStrategy(PerClass.class)
public class CouchbaseConnectionProviderTests extends CbTestBase {
...
}
以下是将使用基类的testclass中的配置 基本选项。
@org.ops4j.pax.exam.Configuration
public Option[] config() {
List<Option> options = super.baseConfig();
options.addAll(Arrays
.asList(features(karafStandardRepo, "scr"),
mavenBundle()
.groupId("se.crossbreed.foundation.persistence")
.artifactId(
"se.crossbreed.foundation.persistence.core")
.versionAsInProject(),
mavenBundle().groupId("io.reactivex")
.artifactId("rxjava").versionAsInProject(),
mavenBundle()
.groupId("se.crossbreed.ports.bundles")
.artifactId(
"se.crossbreed.ports.bundles.couchbase.java-client")
.versionAsInProject(),
mavenBundle()
.groupId("se.crossbreed.foundation.persistence")
.artifactId(
"se.crossbreed.foundation.persistence.provider.couchbase")
.versionAsInProject()));
// above bundle is the one I'm trying to test and where
// this test resides in (project wise)
return options.toArray(new Option[] {});
}
基本配置来自基类
protected List<Option> baseConfig() {
return new ArrayList<Option>(
Arrays.asList(new Option[] {
logLevel(LogLevel.INFO),
karafDistributionConfiguration().frameworkUrl(karafUrl)
.unpackDirectory(new File("target", "exam"))
.useDeployFolder(false),
configureConsole().ignoreLocalConsole(),
mavenBundle().groupId("biz.aQute.bnd")
.artifactId("bndlib").version("${version.bndlib}"),
mavenBundle()
.groupId("se.crossbreed.foundation")
.artifactId(
"se.crossbreed.foundation.core.annotations")
.versionAsInProject(),
mavenBundle()
.groupId("se.crossbreed.foundation")
.artifactId(
"se.crossbreed.foundation.core.interfaces")
.versionAsInProject() }));
}
测试包是
package se.crossbreed.foundation.persistence.provider.couchbase;
CouchbaseConnectionProvider位于同一个包
package se.crossbreed.foundation.persistence.provider.couchbase;
import se.crossbreed.foundation.persistence.core.CbDbConnectionProvider;
public interface CouchbaseConnectionProvider extends CbDbConnectionProvider {
public final static String SVC_NAME = "couchbase.connection.provider";
}
实施:
package se.crossbreed.foundation.persistence.provider.couchbase.impl;
@Component(immediate = true, name =
CouchbaseConnectionProvider.SVC_NAME, provide = {
CouchbaseConnectionProvider.class, CbDbConnectionProvider.class,
CbService.class }, properties = { "providerType=DOCUMENT" },
configurationPolicy = ConfigurationPolicy.require)
public class CouchbaseConnectionProviderImpl implements
CouchbaseConnectionProvider { ... }
以下是Couchbase Provider的项目结构和我未能开始工作的测试(直到测试运行之后;)。
答案 0 :(得分:1)
(我实际上并没有发现您的代码有任何问题,ConfigurationAdmin应该异步工作。测试后出现的新服务仍然看起来像是同步问题。在这种情况下,此设置可能会修复它。 )
您可以使用pax-exam-cm创建出厂配置以及其他选项,而不是在测试方法中创建配置:
@org.ops4j.pax.exam.Configuration
public Option[] config() {
List<Option> options = super.baseConfig();
options.addAll(Arrays
.asList(features(karafStandardRepo, "scr"),
//missing conversion: putAll() needs a Map
ConfigurationAdminOptions.factoryConfiguration(CouchbaseConnectionProvider.SVC_NAME)
.putAll(createProperties(user, pass, host)).create(true).asOption(),
mavenBundle()
.groupId("se.crossbreed.foundation.persistence")
.artifactId(
"se.crossbreed.foundation.persistence.core")
.versionAsInProject(),
mavenBundle().groupId("io.reactivex")
.artifactId("rxjava").versionAsInProject(),
mavenBundle()
.groupId("se.crossbreed.ports.bundles")
.artifactId(
"se.crossbreed.ports.bundles.couchbase.java-client")
.versionAsInProject(),
mavenBundle()
.groupId("se.crossbreed.foundation.persistence")
.artifactId(
"se.crossbreed.foundation.persistence.provider.couchbase")
.versionAsInProject()));
// above bundle is the one I'm trying to test and where
// this test resides in (project wise)
return options.toArray(new Option[] {});
}
Maven设置:
<dependency>
<groupId>org.ops4j.pax.exam</groupId>
<artifactId>pax-exam-cm</artifactId>
<version>${exam.version}</version>
</dependency>
然后,您还可以使用@Inject
注释来获取测试中的CouchbaseConnectionProvider
。
@Inject
CouchbaseConnectionProvider svc;
答案 1 :(得分:0)
我怀疑测试部署了CouchbaseConnectionProvider接口。因此,您尝试使用与实际服务提供的接口不同的接口来检索服务。
您应该尝试为CouchbaseConnectionProvider所在的包添加导入和导出到测试包。
为此,请使用ProbeBuilder
@ProbeBuilder
public TestProbeBuilder probeConfiguration(TestProbeBuilder probe) {
probe.setHeader(Constants.IMPORT_PACKAGE, "..");
probe.setHeader(Constants.EXPORT_PACKAGE, "..");
return probe;
}
答案 2 :(得分:0)
感谢你们的投入 - 我选择自己回答这个问题,因为我的代码中有一个错误并得到了Christoph的帮助。
如果其他人做了我做的事情,我在这里引用他的答案。
问题是我没有在createFactoryConfiguration中将配置所有权设置为匿名via(pid,null)。相反,我使用了createFactoryConfiguration(pid),然后它绑定到当前正在执行的bundle而不是我正在测试的bundle。正如Christoph解释的那样,我可以获得服务包的包位置并明确设置。
干杯, 马里奥
这是ChristophLäubrich的回答
“ChristophLäubrich添加了评论 - 13分钟前
好吧我想我现在知道可能是什么问题了: 您正在使用createFactoryConfiguration(java.lang.String factoryPid),这意味着您将创建一个独家绑定到您的包的配置!因此,不允许其他捆绑包访问配置! 使用createFactoryConfiguration(java.lang.String factoryPid,java.lang.String location)而不是该位置的null参数!这样您就可以创建一个匿名配置,该配置将绑定到获取此配置的第一个bundle。或者,您可以获取目标包的位置并明确地将其作为参数传递,但通常不需要这样做。 如果这仍然不起作用,我们必须仔细查看您的配置,连接到karaf shell(在断点处停止)并获取所有bundle的列表(bundle:list)和所有组件的列表(scr:列表)。 您还应收集有关探测包和应提供服务的包的详细信息(包:导入)。“