Java 阿奎利安+;OSGi+;测试不同的框架属性

Java 阿奎利安+;OSGi+;测试不同的框架属性,java,unit-testing,osgi,apache-felix,arquillian-drone,Java,Unit Testing,Osgi,Apache Felix,Arquillian Drone,我有一个OSGi捆绑包,它在激活过程中从ApacheFelix的config.properties文件中读取一些属性,如果此配置格式错误或不存在,则捆绑包不应该启动。为此,我创建了相应的单元测试,我使用Arquillian进行测试。当我想为不同的Arquillian测试提供不同类型的conf.properties以覆盖每个场景时,问题就出现了 当Arquillian运行测试时,它从/test/resources/文件夹加载framework.properties文件来初始化ApacheFelix

我有一个OSGi捆绑包,它在激活过程中从ApacheFelix的
config.properties
文件中读取一些属性,如果此配置格式错误或不存在,则捆绑包不应该启动。为此,我创建了相应的单元测试,我使用Arquillian进行测试。当我想为不同的Arquillian测试提供不同类型的
conf.properties
以覆盖每个场景时,问题就出现了

当Arquillian运行测试时,它从
/test/resources/
文件夹加载
framework.properties
文件来初始化ApacheFelix,安装测试包并运行测试。现在,我的问题是如何为每个测试用例提供不同的
framework.properties
文件

下面是我使用的Arquillian单元测试:

@RunWith(Arquillian.class)
public class PersistenceLoaderTest {

    @Deployment
    public static Archive<?> createDeployment() {
        final JavaArchive archive = ShrinkWrap.create(JavaArchive.class, "persistence-arq.jar");

        archive.addClass(ProviderLoader.class);
        archive.setManifest(new Asset() {
            public InputStream openStream() {
                OSGiManifestBuilder builder = OSGiManifestBuilder.newInstance();
                builder.addBundleSymbolicName(archive.getName());
                builder.addBundleManifestVersion(2);                    
                builder.addImportPackages("org.osgi.service.startlevel", "org.osgi.service.url");
                builder.addImportPackages(ProviderLoader.class);
                return builder.openStream();
            }
        });

        return archive;
    }

    @ArquillianResource
    public Bundle bundle;

    @ArquillianResource
    BundleContext bundleContext;

    @Test
    public void loadFrameworkConfiguration(){
        // What goes here?
    }
}

这些是我需要更改的属性值,并针对不同的场景进行测试。

据我所知,这是容器级属性,而不是部署级属性,因此需要重新启动容器才能生效

可以通过将arquillian.xml中的容器模式设置为手动来实现这一点

<arquillian>
   <container qualifier="manual_felix" mode="manual">
   </container>
</arquillian>

然后在TestClass中,您可以注入ContainerController,并在每次运行时使用新属性启动它

@RunWith(Arquillian.class)
public class TestA {

   @Deployment(name = "x", managed = false) @TargetsContainer("manual_felix")
   public static Archive<?> deployment() {
      return ShrinkWrap.create....
   }

   @ArquillianResource
   private ContainerController cc;

   @ArquillianResource
   private Deployer d;


   @Test @InSequence(1)
   public void start() {
      cc.start("manual_felix", new Config().add("frameworkProperties", "my-custom-properties-file"));
      d.deploy("x");
   }

   @Test @InSequence(2) @OperatesOnDeployment("x")
   public void shouldDoSomethingInsideX() {
       // executes inside container in context of X
   }
}
@RunWith(Arquillian.class)
公共类遗嘱{
@部署(name=“x”,managed=false)@TargetsContainer(“manual_felix”)
公共静态归档部署(){
返回包络处理。创建。。。。
}
@阿奎利安资源
私人集装箱控制器cc;
@阿奎利安资源
私人部署人员d;
@不连续测试(1)
公开作废开始(){
cc.start(“manual_felix”,new Config().add(“frameworkProperties”,“我的自定义属性文件”);
d、 部署(“x”);
}
@操作部署(“x”)时的顺序测试(2)
公共空间应为Somethinginsidex(){
//在X的上下文中在容器内执行
}
}

您好,谢谢您的回答。有趣的是,如果我将
start()
deploy()
主体放在一个测试方法中,这会允许我在每个测试方法上测试不同的框架属性吗?是的,这是可行的。只有在部署时要执行容器中的某些内容时,才需要拆分测试方法。您无法在尚未部署的内容中进行测试。更新答案。注意container.mode=managed是在类作用域中管理的,这意味着它只能在AfterClass中自动取消部署/停止。如果要在单个TestClass中测试多个启动/停止序列,还需要根据@test手动取消部署/停止容器。您只需在@After中执行即可。谢谢,它很有效。只有一个细节,如果我想在测试中添加一个bundle依赖项(例如到
org.osgi.compendium-5.0.0.jar
),我是否必须使用
@Deployment
创建一个单独的方法,或者是否有更好的方法?我不清楚。您是否已经在部署()中定义的存档的清单中添加了依赖项?我为它创建了一个新问题,您可以阅读详细信息。
@RunWith(Arquillian.class)
public class TestA {

   @Deployment(name = "x", managed = false) @TargetsContainer("manual_felix")
   public static Archive<?> deployment() {
      return ShrinkWrap.create....
   }

   @ArquillianResource
   private ContainerController cc;

   @ArquillianResource
   private Deployer d;


   @Test @InSequence(1)
   public void start() {
      cc.start("manual_felix", new Config().add("frameworkProperties", "my-custom-properties-file"));
      d.deploy("x");
   }

   @Test @InSequence(2) @OperatesOnDeployment("x")
   public void shouldDoSomethingInsideX() {
       // executes inside container in context of X
   }
}