【问题标题】:How to Mock a RequestAttribute value in Sling Model如何在 Sling 模型中模拟 RequestAttribute 值
【发布时间】:2021-10-22 09:20:36
【问题描述】:

我有一个适合@Model(adaptables = SlingHttpServletRequest.class) 的吊索模型,并且有一个请求属性,

@RequestAttribute @选修的 private boolean isRegistration = false;

现在我想模拟上面的参数并用真/假值测试我的代码。为此,我尝试了以下方法,但都没有奏效

   // register adapter factory
    BundleContext bundleContext = MockOsgi.newBundleContext();
    MockSling.setAdapterManagerBundleContext(bundleContext);
    // prepare sling request
    ResourceResolver resourceResolver = MockSling.newResourceResolver(bundleContext);
    MockSlingHttpServletRequest request = new 
    MockSlingHttpServletRequest(resourceResolver);
    request.setAttribute("isRegistration", "true");
     

和,

    @Mock
    SlingHttpServletRequest slingHttpServletRequest;                             
    @Mock
    RequestParameter requestParameter;
Mockito.when(slingHttpServletRequest.getRequestParameter("isRegistration")).thenReturn(requestParameter);
        Mockito.when(requestParameter.getString()).thenReturn("true");

还有其他方法可以模拟这些变量还是我在这里遗漏了什么?

【问题讨论】:

    标签: junit mockito aem sling


    【解决方案1】:

    使用 Mockito 进行 Sling/AEM JUnit 测试不会走得太远。模拟一个非常复杂的产品将是一个永无止境的故事——只需在 Sling 模型中添加几行代码。

    最好使用Sling MocksAEM Mocks

    然后是你的 Sling 模型:

    import org.apache.sling.api.SlingHttpServletRequest;
    import org.apache.sling.models.annotations.Default;
    import org.apache.sling.models.annotations.Model;
    import org.apache.sling.models.annotations.injectorspecific.RequestAttribute;
    
    @Model(adaptables = SlingHttpServletRequest.class)
    public class TestModel1 {
    
        @RequestAttribute
        @Default(booleanValues = false)
        private boolean isRegistration;
    
        public boolean isRegistration() {
            return isRegistration;
        }
    }
    

    可以使用这个基于 Sling Mocks 的 JUnit 测试进行测试。 AEM Mocks 几乎相同,只是它还提供了许多 AEM 服务和功能来进行测试。

    import static org.junit.Assert.*;
    
    import org.apache.sling.models.factory.ModelFactory;
    import org.apache.sling.testing.mock.sling.junit.SlingContext;
    import org.junit.Before;
    import org.junit.Rule;
    import org.junit.Test;
    
    public class TestModel1Test {
    
        @Rule
        public final SlingContext context = new SlingContext();
    
        private ModelFactory modelFactory;
    
        @Before
        public void setUp() {
            context.addModelsForClasses(TestModel1.class);
            this.modelFactory = context.getService(ModelFactory.class);
        }
    
        @Test
        public void isRegistrationTrue() {
            context.request().setAttribute("isRegistration", true);
            TestModel1 model = modelFactory.createModel(context.request(), TestModel1.class);
            assertTrue(model.isRegistration());
        }
    
        @Test
        public void isRegistrationFalse() {
            context.request().setAttribute("isRegistration", false);
            TestModel1 model = modelFactory.createModel(context.request(), TestModel1.class);
            assertFalse(model.isRegistration());
        }
    
        @Test
        public void isRegistrationDefault() {
            TestModel1 model = modelFactory.createModel(context.request(), TestModel1.class);
            assertFalse(model.isRegistration());
        }
    }
    

    PS:不确定,如果你真的想要在你的模型中使用@RequestAttribute-injector。它不是 Sling 中的查询参数。详情请见here

    那么你的 SlingModel 应该是

    import java.util.Optional;
    
    import org.apache.commons.lang3.BooleanUtils;
    import org.apache.sling.api.SlingHttpServletRequest;
    import org.apache.sling.api.request.RequestParameter;
    import org.apache.sling.models.annotations.Model;
    import org.apache.sling.models.annotations.injectorspecific.Self;
    
    @Model(adaptables = SlingHttpServletRequest.class)
    public class TestModel2 {
    
        @Self
        private SlingHttpServletRequest request;
    
        public boolean isRegistration() {
            return Optional.of(request)
                    .map(req -> req.getRequestParameter("isRegistration"))
                    .map(RequestParameter::getString)
                    .map(BooleanUtils::toBooleanObject)
                    .orElse(false);
        }
    }
    

    测试将是:

    import static org.junit.Assert.*;
    
    import org.apache.sling.models.factory.ModelFactory;
    import org.apache.sling.testing.mock.sling.junit.SlingContext;
    import org.junit.Before;
    import org.junit.Rule;
    import org.junit.Test;
    
    public class TestModelTest2 {
    
        @Rule
        public final SlingContext context = new SlingContext();
    
        private ModelFactory modelFactory;
    
        @Before
        public void setUp() {
            context.addModelsForClasses(TestModel2.class);
            this.modelFactory = context.getService(ModelFactory.class);
        }
    
        @Test
        public void isRegistrationTrue() {
            context.request().setQueryString("isRegistration=true");
            TestModel2 model = modelFactory.createModel(context.request(), TestModel2.class);
            assertTrue(model.isRegistration());
        }
    
        @Test
        public void isRegistrationFalse() {
            context.request().setQueryString("isRegistration=false");
            TestModel2 model = modelFactory.createModel(context.request(), TestModel2.class);
            assertFalse(model.isRegistration());
        }
    
        @Test
        public void isRegistrationDefault() {
            TestModel2 model = modelFactory.createModel(context.request(), TestModel2.class);
            assertFalse(model.isRegistration());
        }
    }
    

    这是运行代码的最小 pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>org.example</groupId>
        <artifactId>simpletest</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <properties>
            <maven.compiler.source>8</maven.compiler.source>
            <maven.compiler.target>8</maven.compiler.target>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.apache.sling</groupId>
                <artifactId>org.apache.sling.api</artifactId>
                <version>2.22.0</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.sling</groupId>
                <artifactId>org.apache.sling.models.api</artifactId>
                <version>1.3.8</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-lang3</artifactId>
                <version>3.9</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>3.1.0</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.sling</groupId>
                <artifactId>org.apache.sling.testing.sling-mock.junit4</artifactId>
                <version>3.0.2</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
    </project>
    

    【讨论】:

    • 感谢您的快速响应,但在“context.request()....”时,我遇到了异常“java.lang.RuntimeException:无法初始化 RESOURCERESOLVER_MOCK 资源解析器工厂:org.apache .sling.testing.resourceresolver.MockResourceResolverFactoryOptions.setMangleNamespacePrefixes(Z)Lorg/apache/sling/testing/resourceresolver/MockResourceResolverFactoryOptions;"想到缺少一个依赖项并添加了一个(org.apache.sling.testing.resourceresolver-mock),但问题仍然存在。
    • 根据stackoverflow.com/questions/29978560/…,您缺少“org.apache.sling.api”。但我需要完整的堆栈跟踪才能看到。
    • 我添加了一个适合我的 pom.xml。
    猜你喜欢
    • 2018-04-10
    • 2019-10-09
    • 2017-01-28
    • 1970-01-01
    • 2022-01-14
    • 2015-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多