Hi,
I am writing my first junit test for a workflow process and I am trying to write it using the AEM context (WCM io)
and my workflow process also has a util class method used in it. Here I am facing two problems one with
providing the context (which contains the resource resolver factory and the other objects) to the workflow process execute method in the test method and
the mocking of utils class in Test class.
Note: We can mock the util class if we use powermockito, but powermockito works only with Junit4, but I have to write my test case in Junit5.
below is an excerpt of my code:
@ExtendWith(AemContextExtension.class)
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
public class WorkflowProcessTest {
AemContext context = new AemContext(ResourceResolverType.RESOURCERESOLVER_MOCK);
@Mock
WorkItem workItem;
@Mock
WorkflowData workflowData;
@Mock
WorkflowSession workflowSession;
@Mock
MetaDataMap metaDataMap;
@Mock
private QueryBuilder queryBuilder;
@Mock
private Query qbQuery;
@Mock
ResourceResolverFactory resourceResolverFactory;
@Mock
private SearchResult qbResult;
@Mock
Session adminSession;
@Mock
ResourceResolver resolver;
WorkflowProcess workflowProcess;
@BeforeEach
void setUp() throws LoginException {
resourceResolverFactory = context.registerService(ResourceResolverFactory.class, new MockResourceResolverFactory());
context.registerAdapter(ResourceResolver.class, Session.class, mock(Session.class));
mockPayload();
resolver = context.resourceResolver();
when(resourceResolverFactory.getServiceResourceResolver(any())).thenReturn(resolver);
}
@test
void testExecute() throws RepositoryException,WorkflowException {
//Some more code here
workflowProcess = new WorkflowProcess();
workflowProcess.execute(workItem, workflowSession, metaDataMap);
//workflowProcess = context.registerInjectActivateService(new workflowProcess());
verifyMetadata(metadataNode);
}
private void verifyMetadata(Node metadataNode) throws RepositoryException {
//assert statement here
}
void mockPayload() {
//payload mock here
}
}
Can someone help on those two?
Your help is much appreciated.
Thanks in advance,
Adilakshmi
Solved! Go to Solution.
Views
Replies
Total Likes
I've actually written a blog for this for JUNIT5, with code examples and dependencies:
PowerMock is a Java framework that allows you to unit test code that uses static methods, constructors, and private methods. PowerMock uses a combination of bytecode manipulation and reflection to enable the mocking of these types of methods.
PowerMock is not officially supported by JUnit 5. PowerMock is built on top of EasyMock and provides additional functionality such as the ability to mock static methods, constructors, and private methods. PowerMock uses a different test runner than the one provided by JUnit 5, so it is not directly compatible with JUnit 5.
Alternatively, you can use mockito-inline for inline mocking, it allows you to mock static methods, final classes, and methods, and more.
JUnit 5 provides its own extension model that allows for the creation of custom test runners and the registration of extensions. You could write your own test runner for PowerMock that works with JUnit 5 or use a different mocking framework that is compatible with JUnit 5.
Utils Class:
public class Utils {
public static String getString() {
return "Original string";
}
}
Test Class:
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.mockito.Mockito;
public class MyTest {
@test
public void testStaticMethod() {
// mock the static method of the Utils class
Mockito.mockStatic(Utils.class);
Mockito.when(Utils.getString()).thenReturn("Mocked string");
// create an instance of the class that calls the static method
MyClass myClass = new MyClass();
assertEquals("Mocked string", myClass.getStringFromUtils());
}
}
Hi @adimangalampalli
WCM io library is a utility to mock AEM resources during test time. If you have created a new static method then please avoid using creating a static method as this won't be considered as best practice in java and for the same reason mockito framework doesn't provide the capability to mock static methods by default. You can create services and methods to achieve the same.
However for mocking the static method, please refer below points:
Regards,
Arpit Varshney
I've actually written a blog for this for JUNIT5, with code examples and dependencies:
PowerMock is a Java framework that allows you to unit test code that uses static methods, constructors, and private methods. PowerMock uses a combination of bytecode manipulation and reflection to enable the mocking of these types of methods.
PowerMock is not officially supported by JUnit 5. PowerMock is built on top of EasyMock and provides additional functionality such as the ability to mock static methods, constructors, and private methods. PowerMock uses a different test runner than the one provided by JUnit 5, so it is not directly compatible with JUnit 5.
Alternatively, you can use mockito-inline for inline mocking, it allows you to mock static methods, final classes, and methods, and more.
JUnit 5 provides its own extension model that allows for the creation of custom test runners and the registration of extensions. You could write your own test runner for PowerMock that works with JUnit 5 or use a different mocking framework that is compatible with JUnit 5.
Utils Class:
public class Utils {
public static String getString() {
return "Original string";
}
}
Test Class:
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.mockito.Mockito;
public class MyTest {
@test
public void testStaticMethod() {
// mock the static method of the Utils class
Mockito.mockStatic(Utils.class);
Mockito.when(Utils.getString()).thenReturn("Mocked string");
// create an instance of the class that calls the static method
MyClass myClass = new MyClass();
assertEquals("Mocked string", myClass.getStringFromUtils());
}
}
Thanks @BrianKasingli for your answer, I used the Mockito.mockStatic to mock my util class and it worked.
Thanks,
Adilakshmi
Hi @BrianKasingli , I am having the same problem, that I want to mock a static class in Junit 5 test, which is written using WCM IO extension and AemContext in it. I am able to write the junit without using WCM IO and AemContext, but is it possible to mock the Util class with static methods in my test class in this case.
My Impl class:
@Model(adaptables = {
SlingHttpServletRequest.class }, adapters = MyModel.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL, resourceType = MyModelImpl.RESOURCE_TYPE)
public class MyModelImpl implements MyModel {
protected static final String RESOURCE_TYPE = "some resource type";
@ValueMapValue
private String link;
//other props
@PostConstruct
public void init() {
link = MyUtils.getCorrectUrlForGivenUrlProperty(link);
// other logic
}
@Override
public String getLink() {
return Link;
}
}
MyModelTest class:
@ExtendWith({ AemContextExtension.class, MockitoExtension.class})
class MyModelImplTest {
private final AemContext aemContext = new AemContext();
private MyModel myModel;
@BeforeEach
void setUp() {
//Mockito.mockStatic(MyUtils.class);
//when(MyUtils.getCorrectUrlForGivenUrlProperty("/content/page")).thenReturn("/content/page.html");
aemContext.addModelsForClasses(MyModelImpl.class);
aemContext.load().json("/com/aem/bd/core/models/impl/MyModelImplTest.json", "/content");
}
@Test
void testPropsOfMyModel() {
aemContext.currentResource("/content/myModel");
myModel = aemContext.request().adaptTo(MyModel.class);
assertEquals("/content/page.html", myModel.getLink());
}
}
In the above test class myModel is always coming null in testPropsOfMyModel() method because the aemContext could not initialize MyModel properly because of MyUtils class.
Could you please help me on this?
Thanks in advance.
Suman
Views
Replies
Total Likes
Views
Likes
Replies
Views
Likes
Replies