3. INTRODUCTION • JUnit is the most popular Java unit testing framework. An
open-source framework, it’s used to write and run
repeatable automated tests.
4. WHY UNIT TESTING ?
Unit Test cases are mandatory this days you cannot deploy
your code using Cloud Manager until you have 50% of
code coverage.
• JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage
• Mockito Testing Framework
• wcm.io Test Framework
• Apache Sling Mocks
https://experienceleague.adobe.com/docs/experience-manager-learn/getting-started-wknd-tutorial-
develop/project-archetype/unit-testing.html?lang=en
5. SET UP JUNIT TESTING
Create Java file(AbcTest.java) under core/src/test/java/com/verily/core/models/AbcTest.java
Create Json File(Abc.json) under core/src/test/resources/ com/verily/core/Abc.json
To get JSON File http://localhost:4502/content/verily/us/..../searchresult.infinity.json
Generally, The testcase class name starts or ends with Test word and all test methods generally
begins with “test” word.
Matching expected result with actual result.
8. Setting up AEM test context :
import org.junit.jupiter.api.extension.ExtendWith;
import io.wcm.testing.mock.aem.junit5.AemContext;
import io.wcm.testing.mock.aem.junit5.AemContextExtension;
...
@ExtendWith(AemContextExtension.class)
class SearchResultTest {
private final AemContext aemContext = new AemContext();
private String MOCK_RESOURCE = "/com/verily/core/models/SearchResult.json";
private String PAGE_PATH = "/content/verily/us/en";
• AemContextExtension context can be injected into a Junit test using a custom Junit
Extension named AemContextExtension.
• The SearchResultTest Sling Model is registered into this context
• Mock JCR content structures are created in this context
• Custom OSGi services can be registered in this context
• Provides various common required mock objects and helpers such as
SlingHttpServletRequest objects, various mock Sling and AEM OSGi services such as
ModelFactory, PageManager, Page, Template, ComponentManager, Component,
TagManager, Tag, etc.
9. setUp() Method , Which is executed prior to each @Test method, define a common mock testing state
@BeforeEach
public void setUp() throws Exception {
aemContext.addModelsForClasses(SearchResultTest.class);
aemContext.load().json(MOCK_RESOURCE, PAGE_PATH );
}
• Add models at the package level – addModelsForClasses
• MOCK_RESOURCE Is the JSON file created Under class path - /src/test/resources
• @BeforeAll is used to signal that the annotated method should be executed before all tests in the current test class.
• @BeforeEach is used to signal that the annotated method should be executed before each tests in the current test class.
• @AfterAll, @AfterEach, @afterTestExecution, @postProcessTestInstance, @resolveParameter, @supportsParameter
• resource = aemContext.currentResource(PAGE_PATH); Set the aemContext to respective path and acquire page Object from It.
• Call the Sling Models class header= context.request().adaptTo(Header.class);
https://wcm.io/testing/aem-mock/junit5/apidocs/io/wcm/testing/mock/aem/junit5/AemContextExtension.html#afterAll-
org.junit.jupiter.api.extension.ExtensionContext-
10. • @Test The test annotation tells Junit that the public void method to which it is attached can be run as a test case. To run the method, Junit
first constructs a fresh instance of the class then invokes the annotated method. Any exceptions thrown by the test will be reported by Junit as
a failure. If no exceptions are thrown, the test is assumed to have succeeded.
• What is Junit Assert?
Assert is a method useful in determining Pass or Fail status of a test case, The assert methods are provided by the class
org.junit.Assert, assertions like Boolean, Null, Identical etc.
1.boolean conditions (true or false) : a) assertTrue(condition) b) assertFalse(condition)
2.Null object : a) assertNull(object) b) assertNotNull(object)
3.Identical : a) assertSame(expected, actual), It will return true if expected == actual
b) assertNotSame(expected, actual)
4. Assert Equals : assertEquals(expected, actual)
5. Assert Array Equals assertArrayEquals(expected, actual)
https://junit.org/junit5/docs/current/api/org.junit.jupiter.api/org/junit/jupiter/api/Assertions.html
@Test
public void testGetSfColor() throws Exception {
String msg = footer.getSfColor();
assertNotNull(msg);
assertEquals(msg, "--blue");
}
@Test
public void testGetIsEnabled() throws
Exception {
boolean msg = footer.isEnabled();
assertTrue(msg);
}
12. Returning Static value
Public String firstName() {
return “Unit-Testing”;
}
@Test
Void testFirstName() {
assertEquals(“Unit-Testing”, aemContext.registerService(new SearchResult()). firstName());
}
13. • What is mocking?
Mocking is a process used in unit testing when the unit being tested has external dependencies.
• org.mockito.junit.jupiter.MockitoExtension is a JUnit 5 extension provided by the Mockito library. It allows
library. It allows you to use the Mockito framework to create and inject mocked objects into your
JUnit 5 test classes.
In mocking, the dependencies are replaced by closely controlled replacements objects that simulate the
behavior of the real ones. There are three main possible types of replacement objects - fakes, stubs and mocks.
• Fakes: A Fake is an object that will replace the actual code by implementing the same interface but without interacting
with other objects.
• Stubs: A Stub is an object that will return a specific result based on a specific set of inputs and usually
won’t respond to anything outside of what is programed for the test.
• Mocks: A Mock is a much more sophisticated version of a Stub. It will still return values like a Stub, but it
like a Stub, but it can also be programmed with expectations in terms of how many times each method
should be called, in which order and with what data.
https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html
14. What is Mockito?
It internally uses the Java Reflection API to generate mock objects for a specific
interface. Mock objects are referred to as the dummy or proxy objects used for actual
implementations.
The main purpose of using the Mockito framework is to simplify the development of a test by
mocking external dependencies and use them in the test code.
• @Mock: It is used to mock the objects that helps in minimizing the repetitive mock objects. It
mock objects. It makes the test code and verification error easier to read as parameter names (field
names) are used to identify the mocks. The @Mock annotation is available in
the org.mockito package.
• when(...).thenReturn(...) − Mock implementation of get divide value method of calculated method.
calculated method.
• lenient().when().thenReturn()
"lenient()" method is useful today if you already leverage strict stubbing.
It is very useful because it drives cleaner tests and improved productivity.
15. @ExtendWith(MockitoExtension.class )
class SearchResultTest {
@Mock
private CalculateMethods calculateMethods;
@BeforeEach
public void setupMocks() {
Mockito.when(calculateMethods.divide(6, 3)).thenReturn(2.0);
}
@Test
public void testDivide() {
assertEquals(2.0, calculateMethods.divide(6, 3));
}
}
16. How to Mock @RequestAttribute value in Sling Model
@Model(adaptables = SlingHttpServletRequest.class,
defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class ExampleSlingModel {
@RequestAttribute(name = "websitename")
private String websiteName;
@RequestAttribute
private int version;
@PostConstruct
public void init() {
websiteName = websiteName.concat(":websitename");
version = version * 2;
}
public String getWebsiteName() {
return websiteName;
}
public int getVersion() {
return version;
}
}
public class ExampleSlingModelTest {
@Rule
public final AemContext
aemContext = new AemContext(ResourceResolverType.JCR_MOCK);
private MockSlingHttpServletRequest request;
private ExampleSlingModel underTest;
@Before
public void setUp() throws Exception {
aemContext.addModelsForPackage("com.finning.platform.core.models.u
tils");
request = aemContext.request();
request.setAttribute("websitename", "sourcedcode");
request.setAttribute("version", 5);
}
@Test
public void test_getWebsiteName() {
underTest = request.adaptTo(ExampleSlingModel.class);
Assert.assertEquals("sourcedcode:websitename",
underTest.getWebsiteName());
}
@Test
public void test_getVersion() {
underTest = request.adaptTo(ExampleSlingModel.class);
Assert.assertEquals(10, underTest.getVersion());
} }