Fork me on GitHub

Overview

BRUT supports two approaches for test data:

  1. Stubbed YAML content - Minimal, focused test data you control
  2. Production HCM modules - Real project config via loadProjectContent = true

For component unit tests, stubbed data is strongly preferred.

The content and contentRoot Parameters

Parameter Purpose Example
content Source: Classpath path to YAML /test-content.yaml
contentRoot Target: JCR path for import /content/documents/mysite

@BrxmComponentTest(
    beanPackages = {"org.example.beans"},
    content = "/articles-test-data.yaml",        // Load from classpath
    contentRoot = "/content/documents/mysite"    // Import to this JCR path
)
        

Path Resolution:

  • /articles-test-data.yamlsrc/test/resources/articles-test-data.yaml
  • /org/example/test-data.yamlsrc/test/resources/org/example/test-data.yaml

Why Stub Data?

Benefit Description
Test Isolation Each test controls its own data, no external dependencies
Reproducibility Same results regardless of CMS content, environment, or time
Speed Load only what the test needs vs thousands of production nodes
Documentation YAML files document expected data structure for new developers
Focused Testing Create edge cases, boundary conditions, error scenarios

When to Use Each Approach

Approach Use Case
Stubbed YAML Component unit tests, bean property access, business logic
loadProjectContent = true HST config validation, sitemap/mount testing, integration tests

Basic YAML Structure


# src/test/resources/org/example/news-test-data.yaml
definitions:
  content:
    /news:
      jcr:primaryType: hippostd:folder
      /article-1:
        jcr:primaryType: hippo:handle
        /article-1:
          jcr:primaryType: ns:Article
          ns:title: Test Article
          ns:date: 2024-01-15T10:00:00.000Z
          ns:author: John Doe
        

Key Points

  • Match your @Node beans - jcr:primaryType must match the jcrType in your bean's @Node annotation
  • Use hippo:handle wrapper - Documents need the handle/document structure for HST queries
  • Include required properties - Add properties your component accesses
  • Keep it minimal - Only include data the test actually uses

Handle/Document Structure

brXM documents follow a handle/variant pattern:


/folder                    <- hippostd:folder
  /document-name           <- hippo:handle (container)
    /document-name         <- actual document (same name as handle)
      properties...
        

# Correct structure
/articles:
  jcr:primaryType: hippostd:folder
  /my-article:                          # Handle
    jcr:primaryType: hippo:handle
    /my-article:                        # Document (same name!)
      jcr:primaryType: myproject:Article
      hippo:availability: [live]
      hippostd:state: published
      # ...properties
        

Required Properties

Property Required? Purpose
jcr:primaryType Yes Must match @Node(jcrType)
jcr:mixinTypes: ['mix:referenceable'] Recommended Enables UUID-based references
jcr:uuid Recommended Unique identifier
hippo:availability: [live] Yes Makes document visible to HST queries
hippostd:state: published Yes Marks document as published
Custom properties As needed Data your component accesses

Compound Types (Nested Content)


# Parent document with compound type
/my-document:
  jcr:primaryType: hippo:handle
  /my-document:
    jcr:primaryType: myproject:Page
    hippo:availability: [live]
    hippostd:state: published
    myproject:title: My Page

    # Compound type - child node with its own type
    /myproject:callToAction:
      jcr:primaryType: myproject:CallToAction
      myproject:title: Learn More
      myproject:link: /about
        

Multi-Value Properties


/my-document:
  jcr:primaryType: myproject:PricingCard
  # Single value
  myproject:title: Premium Plan

  # Multi-value property (array)
  myproject:features: ['Feature 1', 'Feature 2', 'Feature 3']

  # Multi-value with complex values
  jcr:mixinTypes: ['mix:referenceable', 'hippo:harddocument']
        

Complete Example


# src/test/resources/petbase-test-content.yaml
/petbase-telecom:
  jcr:primaryType: hippostd:folder
  jcr:mixinTypes: ['hippo:harddocument', 'hippotranslation:translated']
  jcr:uuid: a1b2c3d4-e5f6-7890-abcd-ef1234567890
  hippostd:foldertype: [new-document, new-folder]
  hippotranslation:id: petbase-test-id
  hippotranslation:locale: en

  /herobanners:
    jcr:primaryType: hippostd:folder
    jcr:mixinTypes: ['mix:referenceable']
    jcr:uuid: b2c3d4e5-f6a7-8901-bcde-f12345678901

    /test-hero:
      jcr:primaryType: hippo:handle
      jcr:mixinTypes: ['mix:referenceable']
      jcr:uuid: c3d4e5f6-a7b8-9012-cdef-123456789012

      /test-hero:
        jcr:primaryType: petbase:HeroBanner
        jcr:mixinTypes: ['mix:referenceable']
        jcr:uuid: d4e5f6a7-b8c9-0123-def0-123456789013
        hippo:availability: [live]
        hippostd:state: published
        petbase:title: Welcome to PetBase
        petbase:description: Hello ${USER}, welcome!

        # Compound type (nested content)
        /petbase:callToAction:
          jcr:primaryType: petbase:CallToAction
          petbase:title: Get Started
          petbase:externalLink: /plans
        

File Organization

Keep test YAML files close to the tests that use them:


src/test/
├── java/org/example/
│   ├── ArticleListComponentTest.java
│   └── NewsDetailComponentTest.java
└── resources/org/example/
    ├── articles-test-data.yaml
    └── news-detail-test-data.yaml
        

Comparison

Stubbed Data Production Content
Fast Slower (more data)
Isolated Depends on project state
Reproducible May vary by environment
Documents expectations Tests real config
Unit tests Integration tests

Related