Expand my Community achievements bar.

SOLVED

Junit test for a service

Avatar

Level 8

Hi,

I have a script that cleanup the moved tags on assets and pages.

How to write junit test methods for this service implementation. I have a dropdown which has 2 values(assest(AS),pages(PG))

How to write JUNIT TEST Method

 

package com.yc-demo.aem.scripts.core.cleanupmovedtags;

import com.yc-demo.aem.ac_commons.core.assets.metadata.extraction.Stopwatches;
import com.yc-demo.aem.ac_commons.core.services.ResourceResolverService;
import com.yc-demo.aem.scripts.core.migration.MigrationResourceConsumer;
import com.yc-demo.aem.scripts.core.migration.MigrationRunnable;
import com.atlascopco.aem.scripts.core.propertymigration.ResourceConsumer;
import com.google.common.base.Stopwatch;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

@Component(immediate = true, service = CleanupMovedTagsService.class)
public class CleanupMovedTagsServiceImpl implements CleanupMovedTagsService {

private static final Logger LOGGER = LoggerFactory.getLogger(CleanupMovedTagsServiceImpl.class);

@Reference
private ResourceResolverService resourceResolverService;

@Override
public void cleanupAssets(final ResourceResolver resourceResolver, final CleanupMovedTagsValueMap valueMap, StringBuilder stringBuilder) {
stringBuilder.append("Handling path: ").append(valueMap.getPath()).append("\n\n");

CleanupAssetsResourceConsumer consumer = new CleanupAssetsResourceConsumer(valueMap, stringBuilder);
String filevalue = valueMap.getTypeOfResource();
String query="";

if("AS".equalsIgnoreCase(filevalue)){
query = String.format("SELECT * FROM [dam:Asset] AS s WHERE ISDESCENDANTNODE([%s])", valueMap.getPath());}
else if("PG".equalsIgnoreCase(filevalue)){
query = String.format("SELECT * FROM [cq:PageContent] AS s WHERE ISDESCENDANTNODE([%s])", valueMap.getPath());
}

LOGGER.info("Query: \n{}", query);
ResourceConsumer.resetCounter();

if (resourceResolverService == null) {
LOGGER.error("Could not instantiate ResourceResolver factory");
stringBuilder.append("Could not instantiate ResourceResolver factory");
return;
}

if(resourceResolver != null){
Session session = resourceResolver.adaptTo(Session.class);
if (session != null) {
Set<MigrationRunnable> runnableSet = buildRunnables(resourceResolver, consumer, query, session);

int maxThreads = valueMap.getNbThreads();

LOGGER.info("{} runnables created", runnableSet.size());
LOGGER.info("Max amount of threads assignable : {}", maxThreads);


LOGGER.info("Starting execution of runnables");
Stopwatch stopwatch = Stopwatches.getStartedStopwatch();

runRunnables(runnableSet, maxThreads, valueMap.getTimeout());

LOGGER.info("FINISHED - {} threads used for this script", runnableSet.size());
LOGGER.info("FINISHED - {} pages updated", ResourceConsumer.getCounter());
LOGGER.info("FINISHED - time lapsed : {}", Stopwatches.stopAndGetHoursMinutesSecondsRepresentation(stopwatch));
}
} else {
LOGGER.error("resourceResolver was null, not doing anything");
}
}

// suppress warnings for Thread.currentThread().interrupt()
@SuppressWarnings("CQRules:CWE-676")
private void runRunnables(Set<MigrationRunnable> runnableSet, int maxThreads, int timeout) {
ExecutorService executor = Executors.newFixedThreadPool(maxThreads);

try{
for(MigrationRunnable runnable : runnableSet){
executor.execute(runnable);
}

executor.shutdown();

if(!executor.awaitTermination(timeout, TimeUnit.MINUTES)){
executor.shutdownNow();
}
LOGGER.info("Finishing execution of runnables");

}catch(InterruptedException e){
executor.shutdownNow();
Thread.currentThread().interrupt();
LOGGER.error("Error occurred during thread execution", e);
}
finally {
if(!executor.isShutdown()){
executor.shutdown();
LOGGER.info("Executor shut down");
}
}
}

private Set<MigrationRunnable> buildRunnables(ResourceResolver resourceResolver, MigrationResourceConsumer consumer, String query, Session session) {
Set<MigrationRunnable> runnableSet = new HashSet<>();
QueryManager qm;

try {
qm = session.getWorkspace().getQueryManager();
if (qm != null) {
Query searchQuery = qm.createQuery(query, Query.JCR_SQL2);
NodeIterator it = searchQuery.execute().getNodes();
while (it.hasNext()) {
Node node = it.nextNode();
Resource resource = resourceResolver.getResource(node.getPath());
MigrationRunnable runnable = new MigrationRunnable(resource, consumer, resourceResolverService);
runnableSet.add(runnable);
}
}
} catch (RepositoryException e) {
LOGGER.error("Error occurred during query execution", e);
}

return runnableSet;
}

}
1 Accepted Solution

Avatar

Correct answer by
Community Advisor

@Vani1012 

Would be difficult to provide exact test case but you can do something to start as follow:

import org.apache.sling.api.resource.ResourceResolver;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import static org.mockito.Mockito.*;

public class CleanupMovedTagsServiceTest {

    @Mock
    private ResourceResolverService resourceResolverService;

    @Mock
    private ResourceResolver resourceResolver;

    @InjectMocks
    private CleanupMovedTagsServiceImpl cleanupMovedTagsService;

    @BeforeEach
    public void setUp() {
        MockitoAnnotations.openMocks(this);
    }

    @Test
    public void testCleanupAssets_AssetTypeAS() {
        // Mock CleanupMovedTagsValueMap and set its properties as needed for the test case
        
        CleanupMovedTagsValueMap valueMap = new CleanupMovedTagsValueMap();
        valueMap.setPath("/some/path");
        valueMap.setTypeOfResource("AS");
        // Set other properties as needed
        
        StringBuilder stringBuilder = new StringBuilder();

        // Mock behavior for resourceResolverService or resourceResolver if needed
        // For example:
        // when(resourceResolverService.someMethod()).thenReturn(someValue);
        // when(resourceResolver.adaptTo(Session.class)).thenReturn(mockSession);

        // Call the method to be tested
        cleanupMovedTagsService.cleanupAssets(resourceResolver, valueMap, stringBuilder);

        // Add assertions based on the expected behavior of the method
        // For example:
        // verify(resourceResolverService, times(1)).someMethod();
        // assertEquals(expectedResult, actualResult);
    }

    // Add more test cases for different scenarios if needed
}

 

In this example, the test class CleanupMovedTagsServiceTest uses Mockito to mock the dependencies (ResourceResolverService and ResourceResolver) and injects them into the CleanupMovedTagsServiceImpl instance. It then tests the cleanupAssets method for a specific scenario (e.g., when the asset type is "AS").

You'd need to set up the test data, mock behaviors, and assertions according to the specific behaviors and expectations of the CleanupMovedTagsServiceImpl class and its methods.

Remember to replace placeholders like someMethod() or expectedResult with the actual methods and expected results you're testing against.

View solution in original post

2 Replies

Avatar

Correct answer by
Community Advisor

@Vani1012 

Would be difficult to provide exact test case but you can do something to start as follow:

import org.apache.sling.api.resource.ResourceResolver;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import static org.mockito.Mockito.*;

public class CleanupMovedTagsServiceTest {

    @Mock
    private ResourceResolverService resourceResolverService;

    @Mock
    private ResourceResolver resourceResolver;

    @InjectMocks
    private CleanupMovedTagsServiceImpl cleanupMovedTagsService;

    @BeforeEach
    public void setUp() {
        MockitoAnnotations.openMocks(this);
    }

    @Test
    public void testCleanupAssets_AssetTypeAS() {
        // Mock CleanupMovedTagsValueMap and set its properties as needed for the test case
        
        CleanupMovedTagsValueMap valueMap = new CleanupMovedTagsValueMap();
        valueMap.setPath("/some/path");
        valueMap.setTypeOfResource("AS");
        // Set other properties as needed
        
        StringBuilder stringBuilder = new StringBuilder();

        // Mock behavior for resourceResolverService or resourceResolver if needed
        // For example:
        // when(resourceResolverService.someMethod()).thenReturn(someValue);
        // when(resourceResolver.adaptTo(Session.class)).thenReturn(mockSession);

        // Call the method to be tested
        cleanupMovedTagsService.cleanupAssets(resourceResolver, valueMap, stringBuilder);

        // Add assertions based on the expected behavior of the method
        // For example:
        // verify(resourceResolverService, times(1)).someMethod();
        // assertEquals(expectedResult, actualResult);
    }

    // Add more test cases for different scenarios if needed
}

 

In this example, the test class CleanupMovedTagsServiceTest uses Mockito to mock the dependencies (ResourceResolverService and ResourceResolver) and injects them into the CleanupMovedTagsServiceImpl instance. It then tests the cleanupAssets method for a specific scenario (e.g., when the asset type is "AS").

You'd need to set up the test data, mock behaviors, and assertions according to the specific behaviors and expectations of the CleanupMovedTagsServiceImpl class and its methods.

Remember to replace placeholders like someMethod() or expectedResult with the actual methods and expected results you're testing against.

Avatar

Administrator

@Vani1012 Did you find the suggestions from users helpful? Please let us know if more information is required. Otherwise, please mark the answer as correct for posterity. If you have found out solution yourself, please share it with the community.



Kautuk Sahni