Annotation Interface TestBean


Marks a field or method on a JUnit 5 test class as a test-time bean override.

@TestBean is the Juneau analog of Spring's @MockBean / @TestConfiguration, scoped to a BeanStore overlay rather than a Spring application context. The JuneauBeanStoreExtension discovers @TestBean-annotated members on the test class, builds a TestBeanStore overlay containing the declared overrides, and exposes it via JuneauBeanStoreExtension.getStore() so the test author can wire it into the SUT explicitly (typically via a builder hook such as MockRestClient.Builder.overridingBeanStore(...)).

The wiring is intentionally explicit: the extension does not auto-discover RestContext / Microservice fields on the test class. Test authors write one line of plumbing (.overridingBeanStore(ext.getStore())) and get full control.

The annotation supports two wiring modes via mode(): Mode INJECT (default, fresh-instance with overrides via the SUT's builder) and Mode OVERLAY (existing-instance push/pop against a long-lived SUT's bean store). See JuneauBeanStoreExtension for the full Mode INJECT / Mode OVERLAY contracts.

Applies to:
  • Fields — the field's current value (read via reflection) is registered as the override.
  • Methods — a parameterless factory method whose return type is type-compatible with the override target. Invoked once per scope (per-method for Scope.METHOD, per-class for Scope.CLASS).
Example:

@ExtendWith(JuneauBeanStoreExtension.class) class MyResourceTest { @TestBean MyExternalApi mockApi = Mockito.mock(MyExternalApi.class); @TestBean(name="primary") static MyService primaryService() { return new InMemoryMyService("p"); } @Test void aTest(TestBeanStore store) { var client = MockRestClient.create(MyResource.class) .overridingBeanStore(store) .build(); client.get("/widgets/1").run().assertStatus().is(200); } }

See Also:
Since:
10.0.0
  • Optional Element Summary

    Optional Elements
    Modifier and Type
    Optional Element
    Description
    Wiring mode for the override.
    Qualifier name for the override.
    Lifecycle scope of the override.
    Explicit override target type.
  • Element Details

    • name

      Qualifier name for the override.

      Empty string (the default) means the override is registered as the unnamed bean of its type, matching the behavior of TestBeanStore.override(Class, Object) without a name argument.

      When non-empty, the override is registered under this qualifier so the framework's @Bean(name = "...") parameter resolution can find it. Two @TestBean-declared overrides of the same type but different names are both picked up — the qualifier is the disambiguator.

      Returns:
      The qualifier name. Empty string means "unnamed".
      Since:
      10.0.0
      Default:
      ""
    • type

      Explicit override target type.

      Object.class (the default) is a sentinel meaning "use the annotated member's declared type" — the field's declared type for field overrides, the method's return type for method overrides. This is the common case.

      Set this explicitly when the member's declared type is a supertype of the intended registration type, for example an Object field carrying a MyService value, or a @TestBean Supplier<MyService> factory method whose semantic type is MyService.

      Returns:
      The override target type. Object.class means "use the member's declared type".
      Since:
      10.0.0
      Default:
      java.lang.Object.class
    • scope

      Lifecycle scope of the override.

      Defaults to Scope.METHOD — the override is rebuilt for every test method. Use Scope.CLASS to share the override across all test methods in the class.

      CLASS-scope overrides may only be declared on static fields and static methods. Instance members are not visible at beforeAll time and will be rejected with an error.

      Returns:
      The lifecycle scope.
      Since:
      10.0.0
      Default:
      METHOD
    • mode

      Wiring mode for the override.

      Defaults to Mode.INJECT — the override is installed at SUT construction time via the SUT's overridingBeanStore(...) builder hook. Use Mode.OVERLAY for push/pop overlays against a long-lived SUT that the test has attach-ed to the extension.

      Mixing Mode.INJECT and Mode.OVERLAY annotations on the same scope is rejected at scope-build time with a clear IllegalStateException.

      Returns:
      The wiring mode.
      Since:
      10.0.0
      Default:
      INJECT