Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.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
Mockito Sling模型单元测试:SlingHttpServletRequest中的模拟currentPage_Mockito_Aem_Sling_Sling Models - Fatal编程技术网

Mockito Sling模型单元测试:SlingHttpServletRequest中的模拟currentPage

Mockito Sling模型单元测试:SlingHttpServletRequest中的模拟currentPage,mockito,aem,sling,sling-models,Mockito,Aem,Sling,Sling Models,我在测试Sling模型时遇到了一些问题:由于某种原因,currentPage没有被注入 我的吊索模型如下所示: @Model( adaptables = { SlingHttpServletRequest.class, Resource.class }, resourceType = MyModel.RESOURCE_TYPE) public class MyModel { public static final String RESOURCE_TYPE = "myprojec

我在测试Sling模型时遇到了一些问题:由于某种原因,currentPage没有被注入

我的吊索模型如下所示:

@Model( adaptables = { SlingHttpServletRequest.class, Resource.class }, 
    resourceType = MyModel.RESOURCE_TYPE)
public class MyModel {

   public static final String RESOURCE_TYPE = "myproject/components/renderer";

   @Inject
   private Page currentPage;

   // Model methods, etc.

}
我正在为此编写一些JUnit测试,如下所示:

@RunWith(MockitoJUnitRunner.class)
public class MyModelTest {

  @Rule
  public final AemContext context = new AemContext();

  @Mock
  private SlingHttpServletRequest request;

  private static final String RESOURCE_PATH = "/content/myproject/jcr:content/myModel";
  private static final String PAGE_PATH = "/content/common/page";

  private MyModel myModel;

  @Before
  public final void setUp() throws Exception {
    context.load().json("/models/MyModel.json",RESOURCE_PATH);
    context.load().json("/common-page.json", PAGE_PATH);

    Resource pageResource = context.resourceResolver().getResource(PAGE_PATH);
    Page page = pageResource.adaptTo(Page.class);

    context.currentPage(page);
    context.addModelsForClasses(MyModel.class);
    when(request.getResource()).thenReturn(context.resourceResolver().getResource(RESOURCE_PATH));
    myModel = request.getResource().adaptTo(MyModel.class);
  }

  @Test
  public void simpleLoadTest(){
    assertNotNull(myModel);
  }   
}
这就是我得到的错误:

   [main] WARN org.apache.sling.models.impl.ModelAdapterFactory - Could not adapt to model
  org.apache.sling.models.factory.MissingElementsException: Could not inject all required fields into class com.myproject.common.core.models.MyModel
   at org.apache.sling.models.impl.ModelAdapterFactory.createObject(ModelAdapterFactory.java:558)
   at org.apache.sling.models.impl.ModelAdapterFactory.internalCreateModel(ModelAdapterFactory.java:319)
   at org.apache.sling.models.impl.ModelAdapterFactory.getAdapter(ModelAdapterFactory.java:195)
   at org.apache.sling.testing.mock.sling.MockAdapterManagerImpl.getAdapter(MockAdapterManagerImpl.java:146)
   at org.apache.sling.testing.mock.sling.ThreadsafeMockAdapterManagerWrapper.getAdapter(ThreadsafeMockAdapterManagerWrapper.java:46)
   at org.apache.sling.api.adapter.SlingAdaptable.adaptTo(SlingAdaptable.java:104)
   at org.apache.sling.testing.resourceresolver.MockResource.adaptTo(MockResource.java:110)
   at uk.co.restaurants.common.core.models.MyModelTest.setUp(MyModelTest.java:44)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
   at java.lang.reflect.Method.invoke(Method.java:498)
   at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
   at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
   at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
   at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
   at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
   at org.junit.rules.RunRules.evaluate(RunRules.java:20)
   at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
   at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
   at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
   at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
   at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
   at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
   at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
   at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
   at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
   at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
   at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
   at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
   at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
   Suppressed: org.apache.sling.models.factory.MissingElementException: Could not inject private com.day.cq.wcm.api.Page com.myproject.common.core.models.MyModel.currentPage
       at org.apache.sling.models.impl.ModelAdapterFactory.createObject(ModelAdapterFactory.java:562)
       ... 34 more
   Caused by: org.apache.sling.models.factory.ModelClassException: No injector returned a non-null value!
       at org.apache.sling.models.impl.ModelAdapterFactory.injectElement(ModelAdapterFactory.java:482)
       at org.apache.sling.models.impl.ModelAdapterFactory.createObject(ModelAdapterFactory.java:560)
       ... 34 more
对于其他一些Sling模型测试,注入工作得很好,尽管对于currentPage,我不确定如何继续。 我也找不到关于在Sling模型中模拟currentPage对象的文档

任何帮助都将不胜感激


更新 下面的评论有助于更好地理解此测试的外观。 我做了一些改变,但我的测试仍然失败。现在这些类看起来是这样的:

@RunWith(MockitoJUnitRunner.class)
public class MyModelTest {

  @Rule
  public final AemContext context = new AemContext();

  @Mock
  private SlingHttpServletRequest request;

  @Mock
  AemObjectAnnotationProcessorFactory factory;

  @InjectMocks
  AemObjectInjector aemObjectInjector;

  private static final String RESOURCE_PATH = "/content/myproject/jcr:content/mymodel";
  private static final String PAGE_PATH = "/content/common/page";

  private MyModel mymodel;

  @Before
  public final void setUp() throws Exception {
    context.load().json("/common-page.json", PAGE_PATH);
    Resource pageResource = context.resourceResolver().getResource(PAGE_PATH);
    Page page = pageResource.adaptTo(Page.class);
    context.currentPage(page);

    context.load().json("/models/MyModel.json",RESOURCE_PATH);
    context.request().setServletPath(RESOURCE_PATH);
    context.registerInjectActivateService(factory);
    context.registerService(AemObjectInjector.class, aemObjectInjector);            

    Mockito.when(request.getResource())
      .thenReturn(context.resourceResolver().getResource(RESOURCE_PATH));
    Resource resource = request.getResource();
    mymodel = resource.adaptTo(MyModel.class);
  }

  @Test
  public void simpleLoadTest(){
      assertNotNull(mymodel);
  }  
}

以及带有特定喷油器的更新型号:

@Model(
   adaptables = { SlingHttpServletRequest.class }, 
   resourceType = MyModel.RESOURCE_TYPE)
public class MyModel {

  public static final String RESOURCE_TYPE = "myproject/components/renderer";

  @AemObject
  private Page currentPage;

  // Model methods, etc.

}
setUp()方法不会引发任何异常,也不会引发任何警告。 变量mymodel为null,因此我仍然缺少这里的内容


更新2 我将代码推送到Github,您可以在下面的URL中找到该项目

注:

-在AEM 6.3中进行了测试

-要像往常一样部署项目,请执行以下操作:mvn clean install-PautoInstallPackage

-该项目添加了一些示例页面,以确保Sling模型按预期工作

-Sling模型的功能非常简单:它在内容树上运行,直到找到“isRootPage”属性设置为true的父节点

你有什么问题可以告诉我

提前感谢您提供的任何帮助


更新3 Justin Edelson善意地更正并提供了测试代码。非常感谢他,也感谢艾哈迈德·穆萨利姆(Ahmed Musallam),他一直在追求这一职位,直到他确保一切顺利:)

我的初始代码有两个主要问题: 我试图模拟这个光滑的请求,但是应该使用来自AemContext的请求。 模型未注册

public class MyModelTest {

   @Rule
   public final AemContext context = new AemContext();

   private MockSlingHttpServletRequest request;

   AemObjectAnnotationProcessorFactory factory = new AemObjectAnnotationProcessorFactory();

   AemObjectInjector aemObjectInjector = new AemObjectInjector();

   private static final String RESOURCE_PATH = "/content/parent-page/jcr:content/content/renderer";
   private static final String PAGE_PATH = "/content/parent-page";

   private MyModel mymodel;

   @Before
   public final void setUp() throws Exception {
       request = context.request();
       context.addModelsForClasses(MyModel.class);
       context.load().json("/pages/common-page.json", PAGE_PATH);
       Resource pageResource = 
       context.resourceResolver().getResource(PAGE_PATH);

       Page page = pageResource.adaptTo(Page.class);
       context.currentPage(page);

       context.load().json("/models/MyModel.json", RESOURCE_PATH);
       context.registerInjectActivateService(factory);
       context.registerService(AemObjectInjector.class, aemObjectInjector);


       request.setResource(context.resourceResolver()
         .getResource(RESOURCE_PATH));
       mymodel = request.adaptTo(MyModel.class);
   }

   @Test
   public void simpleLoadTest() {
       assertNotNull(mymodel);
   }

}在模型中使用
@AemObject
(来自
com.adobe.acs.commons.models.injectors.annotation.AemObject
)而不是
@Inject
注释,以便成功注入当前页面


在模型中使用
@AemObject
(来自
com.adobe.acs.commons.models.injectors.annotation.AemObject
)而不是
@Inject
注释,以便成功注入当前页面


您依赖于ACS的
@AemObject
注入器。请记住,该注入器和任何sling注入器都是OSGI服务,并且您的AEM上下文没有注册该服务,即:它不知道AemObjectInjector,这就是为什么您永远不会获得
页面
的非空值

您需要注册注入器和注释处理器:

要注册服务,请查看wcm.io的文档:

注意:注册这些服务时,请确保注册的是服务的真实实例,而不是模拟实例。您需要真实的impl才能正确进行吊索模型注入:

aemObjectInjector=新的aemObjectInjector()
context.registerService(AemObjectInjector.class,AemObjectInjector)

================================================================

更新:

package com.myproject.models;

import javax.annotation.PostConstruct;

import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.models.annotations.Model;

import com.adobe.acs.commons.models.injectors.annotation.AemObject;
import com.day.cq.wcm.api.Page;

@Model(
    adaptables = { SlingHttpServletRequest.class },
    resourceType = MyModel.RESOURCE_TYPE)
public class MyModel {

    public static final String RESOURCE_TYPE = "myproject/components/renderer";

    @AemObject
    private Page currentPage;

    protected final String ROOT_PAGE_PROPERTY = "isRootPage";
    private Page rootPage;

    @PostConstruct
    private void initModel() {
        // Fetches the root language page in order to get the data from that node.
        while (!isRootPage(currentPage)) {
            currentPage = currentPage.getParent();
        }
        rootPage = currentPage;
    }

    private boolean isRootPage(Page selectedPage) {
        return selectedPage.getProperties().get(ROOT_PAGE_PROPERTY, false);
    }

    public String getRootPath() {
            return rootPage.getPath();
    }

}
在查看了您提供的简单回购之后,我看了一下,并修复了测试,使它能够像您希望的那样在回购的分支中工作

为了其他人的利益,以下是:模型类、测试类和json资源:

MyModel.java:

package com.myproject.models;

import javax.annotation.PostConstruct;

import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.models.annotations.Model;

import com.adobe.acs.commons.models.injectors.annotation.AemObject;
import com.day.cq.wcm.api.Page;

@Model(
    adaptables = { SlingHttpServletRequest.class },
    resourceType = MyModel.RESOURCE_TYPE)
public class MyModel {

    public static final String RESOURCE_TYPE = "myproject/components/renderer";

    @AemObject
    private Page currentPage;

    protected final String ROOT_PAGE_PROPERTY = "isRootPage";
    private Page rootPage;

    @PostConstruct
    private void initModel() {
        // Fetches the root language page in order to get the data from that node.
        while (!isRootPage(currentPage)) {
            currentPage = currentPage.getParent();
        }
        rootPage = currentPage;
    }

    private boolean isRootPage(Page selectedPage) {
        return selectedPage.getProperties().get(ROOT_PAGE_PROPERTY, false);
    }

    public String getRootPath() {
            return rootPage.getPath();
    }

}
下面是测试类:MyModelTest.java

package com.myproject.models;

import static org.junit.Assert.*;

import org.apache.sling.api.SlingHttpServletRequest;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import com.adobe.acs.commons.models.injectors.annotation.impl.AemObjectAnnotationProcessorFactory;
import com.adobe.acs.commons.models.injectors.impl.AemObjectInjector;

import io.wcm.testing.mock.aem.junit.AemContext;


@RunWith(MockitoJUnitRunner.class)
public class MyModelTest {

    @Rule
    public final AemContext context = new AemContext();

    @Mock
    private SlingHttpServletRequest request;


    private static final String RESOURCE_PATH = "/content/parent-page/jcr:content/content/renderer";
    private static final String PAGE_PATH = "/content/parent-page";

    private MyModel mymodel;
    private AemObjectInjector aemObjectInjector;
    private AemObjectAnnotationProcessorFactory factory;

    @Before
    public final void setUp() throws Exception {

        // register model
        // NOTE: this is the alternative to creating an adapter/adapter factory.
        context.addModelsForClasses(MyModel.class);

        // load page and resource from json
        context.load().json("/pages/common-page.json", PAGE_PATH);
        context.load().json("/models/MyModel.json", RESOURCE_PATH);

        // set current page to the page path
        context.currentPage(PAGE_PATH);

        // register ACS AemObjectInjector service
        aemObjectInjector = new AemObjectInjector();
        context.registerService(AemObjectInjector.class, aemObjectInjector);

        // adapt request to model
        mymodel = context.request().adaptTo(MyModel.class);
    }

    @Test
    public void simpleLoadTest() {
        // mymodel is NOT null
        assertNotNull(mymodel);
        // mymodel's page has property 'isRootPage=true', therefor it's the root page
        assertEquals(mymodel.getRootPath(), PAGE_PATH);
    }
}
json资源如下所示:

MyModel.json

{
    "jcr:primaryType": "nt:unstructured",
    "sling:resourceType": "myproject/components/renderer"
}
{
    "jcr:primaryType": "cq:Page",
    "jcr:createdBy": "admin",
    "jcr:created": "Fri Nov 03 2017 13:56:12 GMT+0000",
    "jcr:content":
    {
        "jcr:primaryType": "cq:PageContent",
        "jcr:createdBy": "admin",
        "jcr:title": "Parent page",
        "cq:template": "/apps/myproject/templates/common-page",
        "isRootPage": true,
        "jcr:created": "Fri Nov 03 2017 13:56:12 GMT+0000",
        "cq:lastModified": "Fri Nov 03 2017 13:56:12 GMT+0000",
        "sling:resourceType": "myproject/components/page",
        "cq:lastModifiedBy": "admin"
    }
}
公共页面.json

{
    "jcr:primaryType": "nt:unstructured",
    "sling:resourceType": "myproject/components/renderer"
}
{
    "jcr:primaryType": "cq:Page",
    "jcr:createdBy": "admin",
    "jcr:created": "Fri Nov 03 2017 13:56:12 GMT+0000",
    "jcr:content":
    {
        "jcr:primaryType": "cq:PageContent",
        "jcr:createdBy": "admin",
        "jcr:title": "Parent page",
        "cq:template": "/apps/myproject/templates/common-page",
        "isRootPage": true,
        "jcr:created": "Fri Nov 03 2017 13:56:12 GMT+0000",
        "cq:lastModified": "Fri Nov 03 2017 13:56:12 GMT+0000",
        "sling:resourceType": "myproject/components/page",
        "cq:lastModifiedBy": "admin"
    }
}

您依赖于ACS的
@AemObject
注入器。请记住,该注入器和任何sling注入器都是OSGI服务,并且您的AEM上下文没有注册该服务,即:它不知道AemObjectInjector,这就是为什么您永远不会获得
页面
的非空值

您需要注册注入器和注释处理器:

要注册服务,请查看wcm.io的文档:

注意:注册这些服务时,请确保注册的是服务的真实实例,而不是模拟实例。您需要真实的impl才能正确进行吊索模型注入:

aemObjectInjector=新的aemObjectInjector()
context.registerService(AemObjectInjector.class,AemObjectInjector)

================================================================

更新:

package com.myproject.models;

import javax.annotation.PostConstruct;

import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.models.annotations.Model;

import com.adobe.acs.commons.models.injectors.annotation.AemObject;
import com.day.cq.wcm.api.Page;

@Model(
    adaptables = { SlingHttpServletRequest.class },
    resourceType = MyModel.RESOURCE_TYPE)
public class MyModel {

    public static final String RESOURCE_TYPE = "myproject/components/renderer";

    @AemObject
    private Page currentPage;

    protected final String ROOT_PAGE_PROPERTY = "isRootPage";
    private Page rootPage;

    @PostConstruct
    private void initModel() {
        // Fetches the root language page in order to get the data from that node.
        while (!isRootPage(currentPage)) {
            currentPage = currentPage.getParent();
        }
        rootPage = currentPage;
    }

    private boolean isRootPage(Page selectedPage) {
        return selectedPage.getProperties().get(ROOT_PAGE_PROPERTY, false);
    }

    public String getRootPath() {
            return rootPage.getPath();
    }

}
在查看了您提供的简单回购之后,我看了一下,并修复了测试,使它能够像您希望的那样在回购的分支中工作

为了其他人的利益,以下是:模型类、测试类和json资源:

MyModel.java:

package com.myproject.models;

import javax.annotation.PostConstruct;

import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.models.annotations.Model;

import com.adobe.acs.commons.models.injectors.annotation.AemObject;
import com.day.cq.wcm.api.Page;

@Model(
    adaptables = { SlingHttpServletRequest.class },
    resourceType = MyModel.RESOURCE_TYPE)
public class MyModel {

    public static final String RESOURCE_TYPE = "myproject/components/renderer";

    @AemObject
    private Page currentPage;

    protected final String ROOT_PAGE_PROPERTY = "isRootPage";
    private Page rootPage;

    @PostConstruct
    private void initModel() {
        // Fetches the root language page in order to get the data from that node.
        while (!isRootPage(currentPage)) {
            currentPage = currentPage.getParent();
        }
        rootPage = currentPage;
    }

    private boolean isRootPage(Page selectedPage) {
        return selectedPage.getProperties().get(ROOT_PAGE_PROPERTY, false);
    }

    public String getRootPath() {
            return rootPage.getPath();
    }

}
下面是测试类:MyModelTest.java

package com.myproject.models;

import static org.junit.Assert.*;

import org.apache.sling.api.SlingHttpServletRequest;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import com.adobe.acs.commons.models.injectors.annotation.impl.AemObjectAnnotationProcessorFactory;
import com.adobe.acs.commons.models.injectors.impl.AemObjectInjector;

import io.wcm.testing.mock.aem.junit.AemContext;


@RunWith(MockitoJUnitRunner.class)
public class MyModelTest {

    @Rule
    public final AemContext context = new AemContext();

    @Mock
    private SlingHttpServletRequest request;


    private static final String RESOURCE_PATH = "/content/parent-page/jcr:content/content/renderer";
    private static final String PAGE_PATH = "/content/parent-page";

    private MyModel mymodel;
    private AemObjectInjector aemObjectInjector;
    private AemObjectAnnotationProcessorFactory factory;

    @Before
    public final void setUp() throws Exception {

        // register model
        // NOTE: this is the alternative to creating an adapter/adapter factory.
        context.addModelsForClasses(MyModel.class);

        // load page and resource from json
        context.load().json("/pages/common-page.json", PAGE_PATH);
        context.load().json("/models/MyModel.json", RESOURCE_PATH);

        // set current page to the page path
        context.currentPage(PAGE_PATH);

        // register ACS AemObjectInjector service
        aemObjectInjector = new AemObjectInjector();
        context.registerService(AemObjectInjector.class, aemObjectInjector);

        // adapt request to model
        mymodel = context.request().adaptTo(MyModel.class);
    }

    @Test
    public void simpleLoadTest() {
        // mymodel is NOT null
        assertNotNull(mymodel);
        // mymodel's page has property 'isRootPage=true', therefor it's the root page
        assertEquals(mymodel.getRootPath(), PAGE_PATH);
    }
}
json资源如下所示:

MyModel.json

{
    "jcr:primaryType": "nt:unstructured",
    "sling:resourceType": "myproject/components/renderer"
}
{
    "jcr:primaryType": "cq:Page",
    "jcr:createdBy": "admin",
    "jcr:created": "Fri Nov 03 2017 13:56:12 GMT+0000",
    "jcr:content":
    {
        "jcr:primaryType": "cq:PageContent",
        "jcr:createdBy": "admin",
        "jcr:title": "Parent page",
        "cq:template": "/apps/myproject/templates/common-page",
        "isRootPage": true,
        "jcr:created": "Fri Nov 03 2017 13:56:12 GMT+0000",
        "cq:lastModified": "Fri Nov 03 2017 13:56:12 GMT+0000",
        "sling:resourceType": "myproject/components/page",
        "cq:lastModifiedBy": "admin"
    }
}
公共页面.json

{
    "jcr:primaryType": "nt:unstructured",
    "sling:resourceType": "myproject/components/renderer"
}
{
    "jcr:primaryType": "cq:Page",
    "jcr:createdBy": "admin",
    "jcr:created": "Fri Nov 03 2017 13:56:12 GMT+0000",
    "jcr:content":
    {
        "jcr:primaryType": "cq:PageContent",
        "jcr:createdBy": "admin",
        "jcr:title": "Parent page",
        "cq:template": "/apps/myproject/templates/common-page",
        "isRootPage": true,
        "jcr:created": "Fri Nov 03 2017 13:56:12 GMT+0000",
        "cq:lastModified": "Fri Nov 03 2017 13:56:12 GMT+0000",
        "sling:resourceType": "myproject/components/page",
        "cq:lastModifiedBy": "admin"
    }
}

哪个版本的aem模拟?还检查了
page=pageResource.adapto(page.class)之后的
page
不为null。页面没有sling注入器,因此我高度怀疑此sling模型是否正常工作并返回非null页面。您必须注入资源和PageManager(服务),然后使用PageManager#getContainingPage并传递资源以获取页面。我的项目使用ACS Commons,它允许您注入一些其他对象,请查看以下链接以获取更多信息:Sling模型在我的页面中运行良好,并返回预期的输出。啊,我明白了。这是有道理的,请在你的问题中包括这一点。你能分享你的项目吗