How to setProperty() in node object in AEM Sling Model when doing Junit Test?

I have tried to set the property in the the node class in my unit test but was not able to do so. I would like to seek your help in sharing your knowledge on setting node property in AEM Sling MOdel for unit test if you happen to do so before. Thank you!

The implementation is as follows:

@Model(adaptables = SlingHttpServletRequest.class)
public class SlingModelClass {

    @Inject
    private SomeService someService;
    private boolean isShowCaptcha;

    @SlingObject
    private Resource resource;

    private Node node;

    @PostConstruct
    public void setup() {
        node = resource.adaptTo(Node.class);
        isShowCaptcha = someService.isCaptchaHide();
        hideShowTitle(!isShowCaptcha);       <= Test unable to get through this method
    }

    public boolean getIsShowCaptcha() {
        return this.isShowCaptcha;
    }

    public PropertyIterator getPropertiesItems() throws RepositoryException {
        return this.node.getProperties();
    }

    private void hideShowTitle(boolean flag) {
        try {
            node.setProperty("hideTitle", flag);     <= I am getting a null pointer exception at this line
            if(flag) {
                node.setProperty("guideNodeClass", "");
            } else {
                node.setProperty("guideNodeClass", "guideCaptcha");
            }
            node.getSession().save();

        } catch (RepositoryException e) {
            e.printStackTrace();
        }
    }
}

The unit test that I have written:

public class SlingModelClassTest {

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

    @Mock
    private SomeService someService = mock(SomeService .class);

    @Mock
    Resource resource;

    // injects all the mocks into the tested object.
    @InjectMocks
    private SlingModelClass slingModelClass;

    private Node node;

    private static String PATH = "/content/testproject/en/page/sub-page";

    @Before
    public void setUp() {
        context.addModelsForPackage("de.com.adsl.sightly.model");
        context.load().json("/components/textrte.json", PATH);
        context.currentPage(PATH);
        resource = mock(Resource.class);
    }

    @Test
    public void testSetup() {

        context.registerService(SomeService.class, someService);

        slingModelClass.setup();
    }

The error is as follows:

java.lang.NullPointerException
    at de.com.adsl.sightly.model.SlingModelClassTest.aaa(SlingModelClassTest.java:85)
    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:59)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:54)
    at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:305)
    at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:365)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
    at org.junit.runners.ParentRunner$4.run(ParentRunner.java:330)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:78)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:328)
    at org.junit.runners.ParentRunner.access$100(ParentRunner.java:65)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:292)
    at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:305)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:412)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

1 answer

  • answered 2019-12-02 06:40 Florian Salihovic

    This is the wrong pattern. Sling models should not mutate the JCR node. You might get into big trouble when every time a Sling model is instantiated it performs write operations on the repo. Sling model are just supposed to read from the JCR.

    If you need to have some global flag, use the page properties and inheritance to read the flag and overwrite it if necessary. This way, the configuration is done in a controlled way and you only write the property when necessary.

    Just to complete my answer, as suggested by @OliverGebert : the Sling API should be used to work with repository data/as the abstraction layer. The JCR API is considered to be too low level and AEM is basically built on top of Sling. Also, you would need to take care of managing Sling as well as JCR dependencies, which can be a big hassle in long term projects.

How many English words
do you know?
Test your English vocabulary size, and measure
how many words do you know
Online Test
Powered by Examplum