Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Osgi 在wcm.io';s AEM模拟_Osgi_Aem_Sling - Fatal编程技术网

Osgi 在wcm.io';s AEM模拟

Osgi 在wcm.io';s AEM模拟,osgi,aem,sling,Osgi,Aem,Sling,我遵循wcm.io提供的关于正确使用的指南。具体来说,我对注销服务感兴趣。文档提供了用于注册服务的有用代码,但不提供用于取消注册的代码。我已经研究过这个类似的问题,但是给出的解决方案在AEM环境下不起作用 首先,如果我试图注册这样的服务: ServiceReference ref = aemcontext.bundleContext().getServiceReference(MyServiceClass.class.getName()); context.registerInjectActi

我遵循wcm.io提供的关于正确使用的指南。具体来说,我对注销服务感兴趣。文档提供了用于注册服务的有用代码,但不提供用于取消注册的代码。我已经研究过这个类似的问题,但是给出的解决方案在AEM环境下不起作用

首先,如果我试图注册这样的服务:

ServiceReference ref = aemcontext.bundleContext().getServiceReference(MyServiceClass.class.getName());
context.registerInjectActivateService(new MyServlet(), myParams);
它在
bundleContext
中注册,但不在
aemcontext
中注册。确实设置了
ref
对象,但是
aemcontext
从未真正拥有该服务,如果我试图注册一个使用该服务的servlet:

ServiceReference ref = aemcontext.bundleContext().getServiceReference(MyServiceClass.class.getName());
context.registerInjectActivateService(new MyServlet(), myParams);
此调用失败,因为
MyServlet
引用了
MyServiceClass
。工作原理是直接在
aemcontext
上注册服务,例如:

aemcontext.registerService(MyServiceClass.class, new MyServiceClass());
但是,当我尝试取消注册此服务时(如向的问题提供的解决方案中所述),两种解决方案都不起作用。我没有收到任何错误,我假设
ServiceRegistration reg
确实发生了一些问题,但该服务从未从
aemcontext
中注销。如果之后我尝试使用上面的第二个命令再次注册它,则会出现一个错误,表明:

Multiple matches found for unary reference 'myServiceClass' for class...
有人能帮我吗?有没有一种通过AEM mock快速注销服务的方法


谢谢

根据你的评论,我更新了答案:

  • 然后只做两种测试方法。上下文对象在每个测试方法之前重新初始化

  • 注册服务的正确顺序很重要。使用
    registerService
    注册所有模拟服务(例如,使用Mockito创建)。然后对所有应该成为JUnit测试一部分的服务使用
    registerInjectActivateService
    。因为对于
    registerInjectActivateService
    ,所有引用的服务必须在注册之前注册

  • 您不需要嘲笑SlingSettingsService。此服务已经是Sling Mock的一部分,并且还支持更改运行模式

  • 下面是一个示例OSGi服务:

    @Component(service = FakeService.class)
    public class FakeService {
    
        @Reference
        private SlingSettingsService slingSettingsService;
    
        public boolean isAuthor() {
            return slingSettingsService.getRunModes().contains("author");
        }
    
        public boolean isPublish() {
            return slingSettingsService.getRunModes().contains("publish");
        }
    }
    
    以下是此服务的JUnit测试:

    public class FakeTest {
    
        @Rule
        public final AemContext aemcontext = new AemContext();
    
        private FakeService fakeService;
    
        @Before
        public void setup() {
            fakeService = aemcontext.registerInjectActivateService(new FakeService());
        }
    
        @Test
        public void testOnAuthor() {
            aemcontext.runMode("author");
            assertTrue(fakeService.isAuthor());
            assertFalse(fakeService.isPublish());
        }
    
        @Test
        public void testOnPublish() {
            aemcontext.runMode("publish");
            assertFalse(fakeService.isAuthor());
            assertTrue(fakeService.isPublish());
        }
    }
    

    旧答案

  • 您应该不要在OSGi mock(Sling mock、AEM mock)中注销服务。你为什么需要这个?单元测试应该测试您的功能代码,但不能测试OSGi连线是否正常工作。只需接受您不能在单元测试中验证所有内容,即使是像非启动包这样的简单事情。所以你要做健康检查

  • 如果你真的,真的需要这个!您可以扩展测试框架。它是开源的。也许其他人也可以使用它

  • 或者,查看基于Pax考试的单元测试。在我看来,对于“正常”AEM项目来说,它有点过大。但它提供了一个真正的OSGi容器。最大的优势是,它仍然可以作为maven构建的正常部分运行。在AEM项目中,我看到技术感兴趣的人经常引入这种测试。但实际上,这些测试只能证明在单元测试中可以有一个真正的OSGi容器。普通的开发人员不会接触这样的测试,因为这对他们来说太复杂了

  • 最后看一看服务器端JUnit测试。问题是,在构建过程中需要AEM实例和托管测试数据。此外,代码覆盖率等指标也难以衡量。但是,如果您的测试严重依赖AEM特性,我还是建议您这样做。50行模拟LiverRelationshipManager的测试通常毫无价值。然后最好用真正的AEM在服务器端运行它们。另外,AEM项目原型已经提供了集成测试(=服务器端JUnit测试)。但即使在那里,您也必须启动/停止服务,以测试什么


  • 根据你的评论,我更新了答案:

  • 然后只做两种测试方法。上下文对象在每个测试方法之前重新初始化

  • 注册服务的正确顺序很重要。使用
    registerService
    注册所有模拟服务(例如,使用Mockito创建)。然后对所有应该成为JUnit测试一部分的服务使用
    registerInjectActivateService
    。因为对于
    registerInjectActivateService
    ,所有引用的服务必须在注册之前注册

  • 您不需要嘲笑SlingSettingsService。此服务已经是Sling Mock的一部分,并且还支持更改运行模式

  • 下面是一个示例OSGi服务:

    @Component(service = FakeService.class)
    public class FakeService {
    
        @Reference
        private SlingSettingsService slingSettingsService;
    
        public boolean isAuthor() {
            return slingSettingsService.getRunModes().contains("author");
        }
    
        public boolean isPublish() {
            return slingSettingsService.getRunModes().contains("publish");
        }
    }
    
    以下是此服务的JUnit测试:

    public class FakeTest {
    
        @Rule
        public final AemContext aemcontext = new AemContext();
    
        private FakeService fakeService;
    
        @Before
        public void setup() {
            fakeService = aemcontext.registerInjectActivateService(new FakeService());
        }
    
        @Test
        public void testOnAuthor() {
            aemcontext.runMode("author");
            assertTrue(fakeService.isAuthor());
            assertFalse(fakeService.isPublish());
        }
    
        @Test
        public void testOnPublish() {
            aemcontext.runMode("publish");
            assertFalse(fakeService.isAuthor());
            assertTrue(fakeService.isPublish());
        }
    }
    

    旧答案

  • 您应该不要在OSGi mock(Sling mock、AEM mock)中注销服务。你为什么需要这个?单元测试应该测试您的功能代码,但不能测试OSGi连线是否正常工作。只需接受您不能在单元测试中验证所有内容,即使是像非启动包这样的简单事情。所以你要做健康检查

  • 如果你真的,真的需要这个!您可以扩展测试框架。它是开源的。也许其他人也可以使用它

  • 或者,查看基于Pax考试的单元测试。在我看来,对于“正常”AEM项目来说,它有点过大。但它提供了一个真正的OSGi容器。最大的优势是,它仍然可以作为maven构建的正常部分运行。在AEM项目中,我看到技术感兴趣的人经常引入这种测试。但实际上,这些测试只能证明在单元测试中可以有一个真正的OSGi容器。普通的开发人员不会接触这样的测试,因为这对他们来说太复杂了

  • 最后看一看服务器端JUnit测试。问题是,您需要一个AEM实例和托管测试数据