Symptom: Real HST endpoints return errors or stop responding after adding BRUT as a dependency
Cause: BRUT is declared without <scope>test</scope>.
BRUT replaces core HST beans (pipelines, component manager, link creator, etc.) with test-oriented
implementations. When these are on the runtime classpath, they shadow the real production beans.
Fix: Ensure all BRUT dependencies use <scope>test</scope>:
<dependency>
<groupId>org.bloomreach.forge.brut</groupId>
<artifactId>brut-resources</artifactId>
<version>${brut.version}</version>
<scope>test</scope> <!-- Required - do not omit -->
</dependency>
Symptom: NoClassDefFoundError or beans return null properties
Cause: BRUT can't find your @Node annotated beans
// Fix: Specify your bean packages explicitly
@BrxmComponentTest(beanPackages = {"com.example.beans", "com.example.components"})
Symptom: NullPointerException when accessing content
Cause: Content path doesn't match YAML structure
// YAML has: /petbase-telecom/herobanners/test-hero
brxm.setSiteContentBasePath("/content/documents/petbase-telecom");
// Component looks for: herobanners/test-hero
when(paramInfo.getDocument()).thenReturn("herobanners/test-hero");
Symptom: BeanCreationException or missing beans
Cause: Spring config path incorrect or missing imports
@BrxmJaxrsTest(
springConfigs = {"/com/example/test-jaxrs-resources.xml"} // Must start with /
)
Verify your Spring XML has required imports:
<import resource="classpath:/org/hippoecm/hst/site/optional/jaxrs/SpringComponentManager-rest-jackson.xml"/>
Symptom: NoSuchNodeTypeException when importing YAML
Cause: Custom CND types not registered before import
@BeforeEach
void setUp(DynamicComponentTest brxm) throws RepositoryException {
// Register node types BEFORE importing YAML
brxm.registerNodeType("myproject:HeroBanner");
brxm.registerNodeType("myproject:CallToAction");
// Then import content
URL resource = getClass().getResource("/test-content.yaml");
ImporterUtils.importYaml(resource, brxm.getRootNode(),
"/content/documents", "hippostd:folder");
}
Symptom: NullPointerException on brxm.getHstRequest()
Cause: Missing annotation or wrong injection pattern
@BrxmComponentTest(beanPackages = {"com.example.beans"}) // Required!
class MyTest {
// Use parameter injection (recommended)
@Test
void test(DynamicComponentTest brxm) {
assertThat(brxm.getHstRequest()).isNotNull();
}
}
Symptom: getContentBean(request) returns null
Cause: Content path not set or content not published
// 1. Set site content base path
brxm.setSiteContentBasePath("/content/documents/myproject");
# 2. Ensure YAML content has publish state
/my-document:
jcr:primaryType: hippo:handle
/my-document:
jcr:primaryType: myproject:Document
hippo:availability: [live] # Required!
hippostd:state: published # Required!
Symptom: getComponentParametersInfo() returns default values
Cause: Mock not set before calling doBeforeRender
@Test
void testWithParameters(DynamicComponentTest brxm) {
// Set parameters BEFORE calling component method
MyComponentInfo paramInfo = mock(MyComponentInfo.class);
when(paramInfo.getDocument()).thenReturn("path/to/doc");
brxm.setComponentParameters(paramInfo);
// Now call component
component.doBeforeRender(brxm.getHstRequest(), brxm.getHstResponse());
}
| Testing... | Use |
|---|---|
| HST Component (extends CommonComponent) | @BrxmComponentTest |
| JAX-RS REST endpoint (@Path annotated) | @BrxmJaxrsTest |
| Page Model API response | @BrxmPageModelTest |
| POJO/utility class | Plain JUnit (no BRUT needed) |
| Integration with real HST config | Add loadProjectContent = true |
| Error | Likely Cause | Solution |
|---|---|---|
| Endpoints broken after adding BRUT | Missing <scope>test</scope> |
Add <scope>test</scope> to all BRUT dependencies |
NoSuchNodeTypeException |
CND not registered | Call registerNodeType() or add CND pattern |
PathNotFoundException |
Content path wrong | Verify YAML structure matches path |
BeanCreationException |
Spring config error | Check XML syntax and import paths |
NullPointerException on request |
No @BrxmComponentTest |
Add annotation to test class |
NoClassDefFoundError |
Missing bean package | Add to beanPackages parameter |
UnsupportedOperationException |
Method not mocked | Mock the component parameter interface |
InvalidItemStateException |
Session not saved | Call brxm.recalculateRepositoryPaths() after import |
Create src/test/resources/logback-test.xml:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- BRUT logging -->
<logger name="org.bloomreach.forge.brut" level="DEBUG"/>
<!-- HST logging -->
<logger name="org.hippoecm.hst" level="DEBUG"/>
<!-- JCR repository -->
<logger name="org.apache.jackrabbit" level="WARN"/>
<root level="INFO">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
Run with debug output:
mvn test -Dtest=MyTest -Dorg.slf4j.simpleLogger.defaultLogLevel=debug
@BrxmComponentTest(
beanPackages = {"com.example.beans"}
// No loadProjectContent - uses minimal stub
)
class IsolatedComponentTest {
// Test with YAML imports only
}
@BrxmPageModelTest(
loadProjectContent = true,
repositoryDataModules = {"application", "site"}
)
class IntegrationTest {
// Has access to real HST config
}
@BeforeEach
void setUp(DynamicComponentTest brxm) {
// Reset for new request (clears attributes, parameters, session)
brxm.setupForNewRequest();
// Re-initialize component
component = new MyComponent();
component.init(null, brxm.getComponentConfiguration());
}