Fork me on GitHub

Minimal Setup


@BrxmJaxrsTest(resources = {HelloResource.class})
class HelloResourceTest {

    @Test
    void hello_returnsGreeting(DynamicJaxrsTest brxm) {
        String response = brxm.request()
            .get("/site/api/hello/world")
            .execute();

        assertEquals("Hello, World!", response);
    }
}
        

That's it. No Spring XML required.

How It Works

Parameter What it does
resources JAX-RS classes (auto-wrapped in SingletonResourceProvider)
beanPackages Packages for HST content beans (auto-detected)

Auto-detected:

  • HST root from Maven artifactId
  • Test YAML from <testPackage>/imports/*.yaml
  • Jackson JSON support
  • Project content via ConfigService

Request Testing

GET Requests


@Test
void getUser_returnsUserData(DynamicJaxrsTest brxm) {
    User user = brxm.request()
        .get("/site/api/users/123")
        .executeAs(User.class);

    assertEquals("123", user.getId());
}
          

Query Parameters


@Test
void search_returnsFilteredResults(DynamicJaxrsTest brxm) {
    String json = brxm.request()
        .get("/site/api/search")
        .queryParam("q", "news")
        .queryParam("limit", "10")
        .execute();
}
          

Headers


@Test
void secureEndpoint_requiresAuth(DynamicJaxrsTest brxm) {
    String json = brxm.request()
        .get("/site/api/secure/data")
        .withHeader("Authorization", "Bearer token")
        .execute();
}
          

POST with JSON Body


@Test
void createUser_returnsCreated(DynamicJaxrsTest brxm) {
    User created = brxm.request()
        .post("/site/api/users")
        .withJsonBody(new User("John", 25))
        .executeAs(User.class);

    assertEquals("John", created.getName());
}
          

Response Handling

Method Returns Description
execute() String Raw response body
executeAs(Class<T>) T Deserialize JSON to type
executeWithStatus() Response<String> Response with status code
executeWithStatus(Class<T>) Response<T> Typed response with status
assertBody(expected) void Assert response equals expected

// Status code access
Response<User> response = brxm.request()
    .get("/site/api/users/123")
    .executeWithStatus(User.class);

response.status();        // HTTP status code
response.body();          // Typed body
response.isSuccessful();  // true if 2xx
response.isClientError(); // true if 4xx
        

Authentication


@Test
void adminEndpoint_requiresAdminRole(DynamicJaxrsTest brxm) {
    String response = brxm.request()
        .get("/site/api/admin/users")
        .asUser("admin", "admin", "editor")  // username + roles
        .execute();

    assertThat(response).contains("users");
}

@Test
void reportEndpoint_requiresRole(DynamicJaxrsTest brxm) {
    String response = brxm.request()
        .get("/site/api/reports")
        .withRole("manager")  // role-only
        .execute();
}
        

Testing Auth Failures


@Test
void login_fails_forInvalidUser(DynamicJaxrsTest brxm) {
    brxm.authentication().rejectUser("baduser");

    String response = brxm.request()
        .post("/site/api/auth/login")
        .execute();

    assertThat(response).contains("401");
}
          

See Authentication Patterns for more details.

Multiple Resources


@BrxmJaxrsTest(
    beanPackages = {"org.example.model"},
    resources = {UserResource.class, NewsResource.class, AuthResource.class}
)
class ApiTest {
    // All three resources are registered
}
        

Annotation Reference


@BrxmJaxrsTest(
    // Optional: Bean packages (auto-detected from project-settings.xml)
    beanPackages = {"org.example.model"},

    // JAX-RS resources to register (replaces Spring XML)
    resources = {HelloResource.class},

    // Optional: Custom YAML patterns (auto-detected from <package>/imports/)
    yamlPatterns = {"classpath*:custom/path/**/*.yaml"},

    // Optional: Custom CND patterns
    cndPatterns = {"classpath*:custom/namespaces/**/*.cnd"},

    // Optional: Load production HCM content
    loadProjectContent = true,

    // Optional: Override auto-detected HST root
    hstRoot = "/hst:myproject",

    // Optional: Additional Spring configs (for special cases)
    springConfigs = {"/org/example/custom.xml"}
)
        

Spring XML Configuration (Advanced)

For complex scenarios requiring Spring-managed dependencies:


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans-4.1.xsd">

  <import resource="classpath:/org/hippoecm/hst/site/optional/jaxrs/SpringComponentManager-rest-jackson.xml"/>

  <bean id="customRestPlainResourceProviders" class="org.springframework.beans.factory.config.ListFactoryBean">
    <property name="sourceList">
      <list>
        <bean class="org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider">
          <constructor-arg>
            <bean class="com.example.rest.MyResource">
              <constructor-arg ref="someSpringBean"/>
            </bean>
          </constructor-arg>
        </bean>
      </list>
    </property>
  </bean>
</beans>
        

@BrxmJaxrsTest(
    beanPackages = {"com.example.model"},
    springConfigs = {"/com/example/test-jaxrs.xml"}
)
        

Common Issues

Issue Fix
404 Not Found Check @Path annotation matches request URI
Empty response Verify resource is in resources array
JSON parse error Ensure response POJO has matching field names
Mount not found Add test YAML with HST mount config to <package>/imports/

Required Imports


import org.bloomreach.forge.brut.resources.annotation.BrxmJaxrsTest;
import org.bloomreach.forge.brut.resources.annotation.DynamicJaxrsTest;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
        

Related