AEM Context中如何注册带自定义资源映射的ResourceResolverFactory
AEM Context测试中配置ResourceResolver自定义资源映射的正确方法
你之前的代码错误在于直接尝试激活ResourceResolverFactory接口的服务——这个服务是AEM测试上下文自带的系统服务,不能通过registerInjectActivateService重新激活。正确的做法是修改其底层实现类的OSGi配置,或者直接模拟ResourceResolver的映射逻辑。
方法一:通过OSGi配置修改资源映射
直接针对JcrResourceResolverFactoryImpl(ResourceResolverFactory的实际实现类)注册配置,覆盖默认的资源映射规则:
@BeforeEach public void setUp(AemContext context) { // 定义自定义资源映射规则 Map<String, Object> resolverConfig = new HashMap<>(); resolverConfig.put("resource.resolver.mapping", new String[]{ "/content/:/", "/content/dam/:/dam", "/etc/map/:/mymap" }); // 注册配置到ResourceResolverFactory的实现类 context.registerInjectActivateService(org.apache.sling.jcr.resource.internal.JcrResourceResolverFactoryImpl.class, resolverConfig); // 加载测试内容 context.load().json("/path/to/test-content.json", "/content"); }
方法二:模拟ResourceResolver实现自定义映射(单元测试推荐)
如果不想依赖OSGi配置的加载逻辑,直接模拟ResourceResolver的map方法,完全控制映射行为:
import static org.mockito.Mockito.*; import static org.junit.jupiter.api.Assertions.fail; @BeforeEach public void setUp(AemContext context) { // 模拟ResourceResolver实例 ResourceResolver mockResolver = mock(ResourceResolver.class); // 自定义map方法的映射逻辑 when(mockResolver.map(anyString())).thenAnswer(invocation -> { String originalLink = invocation.getArgument(0); // 按规则替换路径 if (originalLink.startsWith("/content/")) { return originalLink.replaceFirst("^/content/", "/"); } else if (originalLink.startsWith("/content/dam/")) { return originalLink.replaceFirst("^/content/dam/", "/dam/"); } else if (originalLink.startsWith("/etc/map/")) { return originalLink.replaceFirst("^/etc/map/", "/mymap/"); } // 不符合规则的路径直接返回原链接 return originalLink; }); // 模拟ResourceResolverFactory,返回上述mock的ResourceResolver ResourceResolverFactory mockFactory = mock(ResourceResolverFactory.class); try { when(mockFactory.getServiceResourceResolver(anyMap())).thenReturn(mockResolver); } catch (LoginException e) { fail("模拟ResourceResolver登录失败"); } // 将模拟的ResourceResolverFactory注册到测试上下文 context.registerService(ResourceResolverFactory.class, mockFactory); // 加载测试内容 context.load().json("/path/to/test-content.json", "/content"); }
注意事项
- 方法一中需要确保你的测试依赖包含
org.apache.sling.jcr.resource包,AEM Mocks通常已经默认引入。 - 方法二更适合单元测试场景,因为它脱离了OSGi配置的依赖,直接控制映射逻辑,测试更稳定。
内容的提问来源于stack exchange,提问作者user19570102
相关产品推荐
相关产品推荐

