sealed interface A2uiComponentStub


Represents a stubbed or overridden Compose implementation for an A2UI component for testing.

This allows tests to isolate specific components by stubbing out their children, or to inject custom mock behaviors for components not natively present in the target catalog.

Summary

Public companion functions

A2uiComponentStub

Creates an A2uiComponentStub that targets a specific component instance by its unique ID.

A2uiComponentStub

Creates an A2uiComponentStub that overrides the rendering logic for all components of a specific type.

Public companion functions

withId

Added in 1.0.0-alpha01
fun withId(
    id: String,
    isReady: @Composable A2uiComponentScope.(A2uiComponentProperties) -> Boolean = { true },
    content: @Composable A2uiComponentScope.(A2uiComponentProperties, Modifier) -> Unit
): A2uiComponentStub

Creates an A2uiComponentStub that targets a specific component instance by its unique ID.

Under the hood, this generates a synthetic component type bound only to this ID.

Note: Registering an ID stub only defines its rendering logic. To make the component appear on the surface initially, you must explicitly include an A2uiComponentPayload with the matching ID in the initialComponents list passed to the A2uiTestController, or supply it dynamically via updateComponent.

import androidx.a2ui.compose.ui.A2uiCatalog
import androidx.a2ui.compose.ui.testing.A2uiComponentPayload
import androidx.a2ui.compose.ui.testing.A2uiComponentStub
import androidx.a2ui.compose.ui.testing.A2uiTestController
import androidx.a2ui.compose.ui.testing.A2uiTestSurface
import androidx.a2ui.model.protocol.A2uiComponentPayload
import androidx.compose.foundation.text.BasicText
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.v2.runComposeUiTest

runComposeUiTest {
    // Define a stub for a specific component ID to isolate it in tests
    val buttonStub =
        A2uiComponentStub.withId("submit_button") { _, modifier ->
            BasicText("Stubbed Submit Button", modifier = modifier.testTag("button_tag"))
        }

    val controller =
        A2uiTestController(
            catalog = A2uiCatalog("test_catalog", emptyList()),
            initialComponents = listOf(A2uiComponentPayload("submit_button")),
            componentStubs = listOf(buttonStub),
        )
    val surface = controller.start()

    setContent { A2uiTestSurface(surface = surface) }

    // Verify the surface renders the stubbed ID content
    onNodeWithTag("button_tag").assertIsDisplayed()
    onNodeWithText("Stubbed Submit Button").assertIsDisplayed()
}
Parameters
id: String

The exact ID of the component instance to stub (e.g., "submit_button").

isReady: @Composable A2uiComponentScope.(A2uiComponentProperties) -> Boolean = { true }

A lambda to evaluate whether the stub is ready to render, defaults to ready.

content: @Composable A2uiComponentScope.(A2uiComponentProperties, Modifier) -> Unit

A composable lambda that emits the UI for this stubbed component.

Returns
A2uiComponentStub

An A2uiComponentStub constrained to the given ID.

withType

Added in 1.0.0-alpha01
fun withType(
    type: String,
    isReady: @Composable A2uiComponentScope.(A2uiComponentProperties) -> Boolean = { true },
    content: @Composable A2uiComponentScope.(A2uiComponentProperties, Modifier) -> Unit
): A2uiComponentStub

Creates an A2uiComponentStub that overrides the rendering logic for all components of a specific type.

The component type may or may not already be present in the test catalog.

import androidx.a2ui.compose.runtime.A2uiProperty
import androidx.a2ui.compose.ui.A2uiCatalog
import androidx.a2ui.compose.ui.testing.A2uiComponentPayload
import androidx.a2ui.compose.ui.testing.A2uiComponentStub
import androidx.a2ui.compose.ui.testing.A2uiTestController
import androidx.a2ui.compose.ui.testing.A2uiTestSurface
import androidx.a2ui.model.protocol.A2uiComponentPayload
import androidx.compose.foundation.text.BasicText
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.v2.runComposeUiTest

runComposeUiTest {
    val urlProp = A2uiProperty.string("url")
    // Define a stub to override all components of type "Image"
    val imageStub =
        A2uiComponentStub.withType("Image") { properties, modifier ->
            val url = properties[urlProp] ?: "no-url"
            BasicText("Stubbed Image: $url", modifier = modifier.testTag("image_tag"))
        }

    val controller =
        A2uiTestController(
            catalog = A2uiCatalog("test_catalog", emptyList()),
            initialComponents =
                listOf(
                    A2uiComponentPayload(
                        id = "header_image",
                        type = "Image",
                        properties = mapOf("url" to "https://example.com/photo.png"),
                    )
                ),
            componentStubs = listOf(imageStub),
        )
    val surface = controller.start()

    setContent { A2uiTestSurface(surface = surface) }

    onNodeWithTag("image_tag").assertIsDisplayed()
    onNodeWithText("Stubbed Image: https://example.com/photo.png").assertIsDisplayed()
}
Parameters
type: String

The string type identifier (e.g., "Image", "Video") to override.

isReady: @Composable A2uiComponentScope.(A2uiComponentProperties) -> Boolean = { true }

A lambda to evaluate whether the stub is ready to render, defaults to ready.

content: @Composable A2uiComponentScope.(A2uiComponentProperties, Modifier) -> Unit

A composable lambda that emits the UI for this component type.

Returns
A2uiComponentStub

An A2uiComponentStub constrained to the given type.