Expand my Community achievements bar.

Guidelines for the Responsible Use of Generative AI in the Experience Cloud Community.
SOLVED

Junit5 shows always 0% coverage in Intellij

Avatar

Level 2

Hi All,

I have created Junit5 class for the below code.

package com.test.core.models;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.Required;
import org.apache.sling.models.annotations.injectorspecific.Self;
import org.apache.sling.models.annotations.injectorspecific.SlingObject;
import org.apache.sling.settings.SlingSettingsService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.PostConstruct;
import javax.inject.Inject;

import java.io.IOException;

@Model(adaptables = SlingHttpServletRequest.class)
public class RedirectionModel {
    @Deleted Account
    private SlingHttpServletRequest request;

    @SlingObject
    private SlingHttpServletResponse response;

    @inject
    @Required
    private String redirectURL;
    @inject
    private SlingSettingsService slingSettingsService;
    private static final Logger log = LoggerFactory.getLogger(RedirectionModel.class);

    @PostConstruct
    protected void init() {
        log.info("PageRedirectModel: init method");
        Resource resource ;
        resource = request.getResource();
        String redirectTarget = resource.getResourceResolver().map(request, redirectURL);
        log.info("redirectTarget Url {}",redirectTarget);
        if (redirectTarget != null && redirectTarget.startsWith("/content/")) {
            redirectTarget += ".html";

        }
        try {
            log.info("in try");
            response.sendRedirect(redirectTarget);

        } catch (IOException e) {
            log.error("[RedirectUtils] Failed to execute redirect", e);
        }
    }
}

 

Junit5 class

package com.test.core.models;

import com.day.cq.wcm.api.Page;
import io.wcm.testing.mock.aem.junit5.AemContext;
import io.wcm.testing.mock.aem.junit5.AemContextExtension;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletRequest;
import org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletResponse;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.Mockito;

import static org.junit.jupiter.api.Assertions.*;
@ExtendWith(AemContextExtension.class)
public class RedirectionModelTest {

    public RedirectionModel redirectionModel;
    private Page page;
    private Resource resource;
    private  String RedirectUrl;
    @Mock
    MockSlingHttpServletRequest request;
    @Mock
    MockSlingHttpServletResponse response;
    @BeforeEach
    public void setUp(AemContext context) throws Exception{
        RedirectUrl="/content/mykp/homepage";
        page = context.create().page("/content/mykp/en");
        resource = context.resourceResolver().getResource("/content/mykp/en");
        redirectionModel=resource.adaptTo(RedirectionModel.class);

    }

    @test
    public void init() {
        String redirectTarget = resource.getResourceResolver().map(request, this.RedirectUrl);
        if(redirectTarget.startsWith("/content")&& redirectTarget!=null) {
            redirectTarget += ".html";
        }
        assertEquals("/content/mykp/homepage.html",redirectTarget);

    }
}

after run Test with code converge it is showing me always 0% in  IntelliJ.

did i miss anything?

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

@bhavi50 , You've to write test cases for negative/exception cases to get coverage for the uncovered lines. If you notice, the lines that are not covered in code coverage are the cases where you encounter the exception or when the path doesn't start with "/content". 

Add a new test case by creating the page under a non-content path, for instance under /conf or /test, at that time if condition at line #40 is not satisfied and will be covered. 

 

 

View solution in original post

13 Replies

Avatar

Community Advisor

@bhavi50 Yes, you're missing a few things. 

  1. RedirectionModel is registered with SlingHttpServletRequest, but in the RedirectionModelTest class you're trying to adapt it from Resource, which will just return null model and init() method in Sling Model is never called. 
  2. redirectURL param is not set in the request to set the Required field for redirection.
  3. init() method in test class is not really testing the RedirectionModel, instead it is testing some made up data within the method. 

 

You can refer this code to properly unit test the model and which will give you the code coverage

import io.wcm.testing.mock.aem.junit5.AemContext;
import io.wcm.testing.mock.aem.junit5.AemContextExtension;
import org.apache.sling.api.resource.Resource;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

import static org.junit.jupiter.api.Assertions.assertEquals;
@ExtendWith(AemContextExtension.class)
public class RedirectionModelTest {

    AemContext context = new AemContext();
    @BeforeEach
    public void setUp() throws Exception{

        context.create().page("/content/mykp/en");
        Resource resource = context.resourceResolver().getResource("/content/mykp/en");
        context.request().setAttribute("redirectURL", "/content/mykp/homepage");
        context.currentResource(resource);
        context.request().adaptTo(RedirectionModel.class);

    }

    @Test
    public void init() {
        assertEquals("/content/mykp/homepage.html",context.response().getHeader("location"));
    }
}

Avatar

Level 2

Still it's showing 0% coverage.

Screenshot (3).png

 

It gives the error and JUnitt Test failed.

 

Screenshot (4).png

 

Avatar

Community Advisor

I suspect the problem is with unused SlingSettingsService variable in your sling model. Remove the following lines from your model and try the test again. 

 

@Inject
private SlingSettingsService slingSettingsService;

Avatar

Level 2

I removed 

@Inject
private SlingSettingsService slingSettingsService;

but still showing 0% coverage. 

 

 

context.response().getHeader("location"));

on this line given the null value for us. 

Avatar

Community Advisor

@bhavi50 As the next step, I recommend running the unit test in Debug and seeing exactly where you are getting the null. Is the response object returning null, or is there no location header in the response object?

 

Add break point at this line in IDE and run it in Debug - 

assertEquals("/content/mykp/homepage.html",context.response().getHeader("location"));


I tested the same code in my local IDE, and I've had no issues running the test class, and I can see the coverage as well. Below is the sling model if you need to refer 

@Model(adaptables = SlingHttpServletRequest.class)
public class RedirectionModel {
    @Self
    private SlingHttpServletRequest request;

    @SlingObject
    private SlingHttpServletResponse response;

    @Inject
    @Required
    private String redirectURL;
    private static final Logger log = LoggerFactory.getLogger(RedirectionModel.class);

    @PostConstruct
    protected void init() {
        log.info("PageRedirectModel: init method");
        Resource resource ;
        resource = request.getResource();
        String redirectTarget = resource.getResourceResolver().map(request, redirectURL);
        log.info("redirectTarget Url {}",redirectTarget);
        if (redirectTarget != null && redirectTarget.startsWith("/content/")) {
            redirectTarget += ".html";

        }
        try {
            log.info("in try");
            response.sendRedirect(redirectTarget);

        } catch (IOException e) {
            log.error("[RedirectUtils] Failed to execute redirect", e);
        }
    }
}

Avatar

Level 2

Why not showing on my IDE still its showing 0% coverage.

Is there required any Dependency?

Avatar

Community Advisor

@bhavi50 You're running the code coverage through IntelliJ, which doesn't need any dependencies. And you see the coverage as 0%, so you're not missing anything.

The focus is more on the code coverage; the foremost thing is ensuring your test cases are passing without errors.

Are you still getting the null?

Avatar

Level 2

We covered the 76.5% coverage but for our project we need 80% coverage.

Line number 40, 47 and 48 not be covered.

what we have to do for that?

 

screenshot1.jpeg

Avatar

Correct answer by
Community Advisor

@bhavi50 , You've to write test cases for negative/exception cases to get coverage for the uncovered lines. If you notice, the lines that are not covered in code coverage are the cases where you encounter the exception or when the path doesn't start with "/content". 

Add a new test case by creating the page under a non-content path, for instance under /conf or /test, at that time if condition at line #40 is not satisfied and will be covered. 

 

 

Avatar

Level 2

Hi @Lokesh_Vajrala ,

We tried multiple ways still not covered that 2 line, can you help me to cover any one line? Can you please help me?

Avatar

Community Advisor

Where was it failing? 

 

You need something like the following to cover the line #40, which should give you more than 80% coverage except the exception block. 

    // BeforeEach method runs before running any test case, so you need to create page under non-content directory to test the negative scenario.   
@Test public void testInvalidRedirectTarget() { context.create().page("/conf/mykp/en"); Resource resource = context.resourceResolver().getResource("/conf/mykp/en"); context.request().setAttribute("redirectURL", "/conf/mykp/homepage"); context.currentResource(resource); context.request().adaptTo(RedirectionModel.class); assertEquals("/conf/mykp/homepage",context.response().getHeader("location")); }

 

Avatar

Level 2

Hi @Lokesh_Vajrala ,

We already done but still line 40 is not covered, can you help to cover line no 40, 47 and 48?

screenshot1.jpeg

Avatar

Community Advisor

@bhavi50 

can you check if you have enabled coverage for your project in intellij setting or not or if the class has been excluded from the coverage by mistake?

https://www.jetbrains.com/help/idea/configuring-code-coverage-measurement.html