Expand my Community achievements bar.

SOLVED

Unit test MSM Custom Rollout Configuration

Avatar

Level 1

Hello, im new to AEM and Im trying to learn how to create a custom rollout configuration but Im wondering how I can test the code below with Mockito.

import javax.jcr.RepositoryException;

import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ValueMap;
import org.osgi.service.component.annotations.Component;

import com.day.cq.wcm.api.WCMException;
import com.day.cq.wcm.msm.api.LiveActionFactory;
import com.day.cq.wcm.msm.api.LiveRelationship;
import com.day.cq.wcm.msm.commons.BaseAction;
import com.day.cq.wcm.msm.commons.BaseActionFactory;

@Component(service = LiveActionFactory.class, property = {LiveActionFactory.LIVE_ACTION_NAME + "=" + ExampleActionFactory.LIVE_ACTION_NAME })
public class ExampleActionFactory extends BaseActionFactory<BaseAction> {

	public static final String LIVE_ACTION_NAME = "SampleCustomRollout";
	
@Override public String createsAction() { return LIVE_ACTION_NAME; }
@Override protected ExampleAction newActionInstance(ValueMap config) throws WCMException { return new ExampleAction(config, this); } private static final class ExampleAction extends BaseAction { public ExampleAction(ValueMap config, BaseActionFactory<? extends LiveAction> liveActionFactory) { super(config, liveActionFactory); } protected boolean handles(Resource source, Resource target, LiveRelationship relation, boolean resetRollout) throws RepositoryException, WCMException { return (relation.getStatus().isPage() && source != null && target!= null); } protected void doExecute(Resource source, Resource target, LiveRelationship relation, boolean resetRollout) throws RepositoryException, WCMException { System.out.print("I am custom rollout");
//more logic } } }

 

Any tips or sample code is very much appreciated.

1 Accepted Solution

Avatar

Correct answer by
Community Advisor
2 Replies

Avatar

Correct answer by
Community Advisor

Avatar

Level 4

I would try to implement the LiveActionFactory rather than create a new one based on BaseActionFactory. 

 

As for all AEM Unit tests for Services, start by adding a mock context, mock your class' dependencies and inject those mocks into a mock object of your class. Then create a general setup method for all following tests. Finally, create your test methods. In each test method, intercept methods that would return "null" because of your empty mock objects, and force them to return some value of your choice. And assert the output of your method with certain input (parameters).

@ExtendWith({ AemContextExtension.class, MockitoExtension.class })
class MyServiceImplTest {

    private final AemContext aemContext = new AemContext(ResourceResolverType.JCR_MOCK);

    @Mock
    private ResourceResolverFactory resourceResolverFactory;

    @Mock
    private ResourceResolver resourceResolver;

    @Mock
    private Resource resource;

    @Mock
    private MyServiceImpl.Configuration configuration;

    @InjectMocks
    private MyServiceImpl myServiceImpl;

    @BeforeEach
    void setup() {
        aemContext.registerService(ResourceResolverFactory.class, resourceResolverFactory);

        myServiceImpl = new MyServiceImpl();

        MockitoAnnotations.initMocks(this);
    }

    @test
    void test(){
        lenient().when(configuration.enabled()).thenReturn(true); //Intercept your service's configration enabled property and always return true.

        MyServiceImpl.activate(configuration);

        String actual = myServiceImpl.myMethod(myParam);
        String expected = "myOutput";

        assertEquals(expected, actual);
    }
}