> For AI agents: the complete documentation index is available at https://nhanbe.id.vn/llms.txt, the full documentation bundle is available at https://nhanbe.id.vn/llms-full.txt.

# Testing and Debugging

## Unit Test

- What it cover: Sling Models, services, utility logic in isolation
- Tooling: JUnit 5, Mockito, wcm.io AEM Mocks (`AEMContext`)

## Unit Test for Sling Models

`AEMContext` from `io.wcm.mock.aem.junit5` gives an in-memory JCR+Sling+AEM context, so you can register a model, load content, and assert on the result - no running instance required.

```java
import io.wcm.testing.mock.aem.junit5.AemContext;
import io.wcm.testing.mock.aem.junit5.AemContextExtension;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

import static org.junit.jupiter.api.Assertions.assertEquals;

@ExtendWith(AemContextExtension.class)
class HelloModelTest {

    private final AemContext ctx = new AemContext();

    @Test
    void rendersTitle() {
        ctx.addModelsForClasses(HelloModel.class);
        ctx.load().json("/com/mysite/core/models/HelloModel.json", "/content/hello");

        Resource resource = ctx.resourceResolver().getResource("/content/hello");
        HelloModel model = resource.adaptTo(HelloModel.class);

        assertEquals("Hello, World", model.getTitle());
    }
}
```

Put the fixture JSON under `src/test/resources` mirroring the package. For a request-adaptable model, use `ctx.request()` as the adaptable and set `ctx.currentResource(...)` first.

## Mocking OSGi services

Register mocks with Mockito and inject them into the context so ur model's `@OSGiService`/`@Reference` dependencies resolve:

```java
MyService svc = mock(MyService.class);
when(svc.compute()).thenReturn("stubbed");
ctx.registerService(MyService.class, svc);
```

## What to unit-test

- Getter logic, defaults, and null/empty handling.
- Branching in `@PostContruct`
- Any Business rule (formatting, filtering, validation fallbacks)

## Code coverage and quality gates

Jacoco

## Debugging toolkit

### Logs

- `crx-quickstart/log/error.log` the primary log.

### CRXDE Lite

Confirm a property actually persisted, check `sling:resourceType`, inspect ACLs.

### Request process, recent requets

`system/console/requests` shows full Sling processing of a request; which script/servlet rendered it, included resources, and timings.

### Component and clientlib resolution

- Append `?debugClientLibs=true` to a page to load clientlibs unminified and see exactly which files are included.
- Use `/libs/granite/ui/content/dumplibs.html` to inspect clientlib categories and dependencies.
- The HTL/Sling **WCM debug filter** (`?wcmmode=disabled`) renders the page without editing chrome.

## JaCoCo Unit Test Coverage

1. Navigate to your projects root `/pom.xml`
2. Add following line to `<properties>` section
3. Add JaCoCo Plugin

```xml
<plugin>
     <groupId>org.jacoco</groupId>
     <artifactId>jacoco-maven-plugin</artifactId>
     <version>0.8.8</version>
     <executions>
         <execution>
         <id>prepare-and-report</id>
         <goals>
         <goal>prepare-agent</goal>
         <goal>report</goal>
         </goals>
         </execution>
         <execution>
         <id>report-aggregate</id>
         <phase>verify</phase>
         <goals>
         <goal>report-aggregate</goal>
         </goals>
         <configuration>
             <outputDirectory>${project.basedir}/../target/site/jacoco-aggregate</outputDirectory>
             <excludes>
                 <exclude>ui.apps/**/*</exclude>
                 <exclude>ui.tests/**/*</exclude>
                 <exclude>it.tests/**/*</exclude>
             </excludes>
         </configuration>
         </execution>
     </executions>
</plugin>
```
