# androidx.a2ui.compose.ui.testing

## Interfaces

|---|---|
| `https://developer.android.com/reference/kotlin/androidx/a2ui/compose/ui/testing/A2uiComponentStub` | Represents a stubbed or overridden Compose implementation for an A2UI component for testing. |
| `https://developer.android.com/reference/kotlin/androidx/a2ui/compose/ui/testing/A2uiTestController` | A controller for orchestrating A2UI component and surface tests. |

## Composables

|---|---|
| `https://developer.android.com/reference/kotlin/androidx/a2ui/compose/ui/testing/A2uiTestSurface.composable` | A test utility composable that mounts the root component of the specified `https://developer.android.com/reference/kotlin/androidx/a2ui/model/processor/A2uiSurfaceModel` to allow testing individual components or entire surfaces in isolation. |

## Top-level functions summary

|---|---|
| `https://developer.android.com/reference/kotlin/androidx/a2ui/model/protocol/A2uiComponentPayload` | `https://developer.android.com/reference/kotlin/androidx/a2ui/compose/ui/testing/package-summary#A2uiComponentPayload(kotlin.String,kotlin.collections.Map)(id: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html, properties: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.collections/-map/index.html<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html, https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html?>)` Creates an `https://developer.android.com/reference/kotlin/androidx/a2ui/model/protocol/A2uiComponentPayload` for an ID-scoped test stub without requiring a dummy component type. |
| `https://developer.android.com/reference/kotlin/androidx/a2ui/compose/ui/testing/A2uiTestController` | `https://developer.android.com/reference/kotlin/androidx/a2ui/compose/ui/testing/package-summary#A2uiTestController(androidx.a2ui.compose.ui.A2uiCatalog,kotlin.collections.Map,kotlin.collections.List,kotlin.collections.Map,kotlin.collections.List)( catalog: https://developer.android.com/reference/kotlin/androidx/a2ui/compose/ui/A2uiCatalog, theme: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.collections/-map/index.html<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html, https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html?>, initialComponents: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.collections/-list/index.html<https://developer.android.com/reference/kotlin/androidx/a2ui/model/protocol/A2uiComponentPayload>, initialData: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.collections/-map/index.html<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html, https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html?>, componentStubs: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.collections/-list/index.html<https://developer.android.com/reference/kotlin/androidx/a2ui/compose/ui/testing/A2uiComponentStub> )` Creates a `https://developer.android.com/reference/kotlin/androidx/a2ui/compose/ui/testing/package-summary#A2uiTestController(androidx.a2ui.compose.ui.A2uiCatalog,kotlin.collections.Map,kotlin.collections.List,kotlin.collections.Map,kotlin.collections.List)` that can be used to drive tests. |

## Extension functions summary

|---|---|
| `inline T?` | `<T : https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html?> https://developer.android.com/reference/kotlin/androidx/a2ui/compose/ui/testing/A2uiTestController.https://developer.android.com/reference/kotlin/androidx/a2ui/compose/ui/testing/package-summary#(androidx.a2ui.compose.ui.testing.A2uiTestController).getData(kotlin.String)(path: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html)` Reads a value from the underlying data model at the specified JSON pointer path and casts it to the requested type `https://developer.android.com/reference/kotlin/androidx/a2ui/compose/ui/testing/package-summary#(androidx.a2ui.compose.ui.testing.A2uiTestController).getData(kotlin.String)`. |

## Top-level functions

### A2uiComponentPayload

Artifact: [androidx.a2ui.compose:compose-ui-testing](https://developer.android.com/jetpack/androidx/releases/a2ui-compose) [View Source](https://cs.android.com/search?q=file:androidx/a2ui/compose/ui/testing/A2uiComponentStub.kt+function:A2uiComponentPayload)

```
fun A2uiComponentPayload(id: String, properties: Map<String, Any?> = emptyMap()): A2uiComponentPayload
```

Creates an `https://developer.android.com/reference/kotlin/androidx/a2ui/model/protocol/A2uiComponentPayload` for an ID-scoped test stub without requiring a dummy component type.

This overload is strictly reserved for components stubbed via `https://developer.android.com/reference/kotlin/androidx/a2ui/compose/ui/testing/A2uiComponentStub#withId(kotlin.String,kotlin.Function2,kotlin.Function3)`.

```kotlin
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 textProp = A2uiProperty.string("text")
    val stub =
        A2uiComponentStub.withId("title_stub") { props, modifier ->
            val title = props[textProp] ?: ""
            BasicText(title, modifier = modifier.testTag("title_tag"))
        }

    // Use the ID-only A2uiComponentPayload helper specifically designed for ID stubs
    val initialPayload =
        A2uiComponentPayload(id = "title_stub", properties = mapOf("text" to "Welcome to A2UI"))

    val controller =
        A2uiTestController(
            catalog = A2uiCatalog("test_catalog", emptyList()),
            initialComponents = listOf(initialPayload),
            componentStubs = listOf(stub),
        )
    val surface = controller.start()

    setContent { A2uiTestSurface(surface = surface) }

    onNodeWithTag("title_tag").assertIsDisplayed()
    onNodeWithText("Welcome to A2UI").assertIsDisplayed()
}
```

| Parameters |
|---|---|
| `id: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html` | The unique identifier of the stubbed component. |
| `properties: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.collections/-map/index.html<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html, https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html?> = emptyMap()` | The initial property map to configure the stub. |

| Returns |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/a2ui/model/protocol/A2uiComponentPayload` | An `https://developer.android.com/reference/kotlin/androidx/a2ui/compose/ui/testing/package-summary#A2uiComponentPayload(kotlin.String,kotlin.collections.Map)` configured for the ID stub. |

| Throws |
|---|---|
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-illegal-argument-exception/index.html` | If used for a component ID that has not been registered as an ID stub via `https://developer.android.com/reference/kotlin/androidx/a2ui/compose/ui/testing/A2uiComponentStub#withId(kotlin.String,kotlin.Function2,kotlin.Function3)`. |

### A2uiTestController

Artifact: [androidx.a2ui.compose:compose-ui-testing](https://developer.android.com/jetpack/androidx/releases/a2ui-compose) [View Source](https://cs.android.com/search?q=file:androidx/a2ui/compose/ui/testing/A2uiTestController.kt+function:A2uiTestController)

```
fun A2uiTestController(
    catalog: A2uiCatalog,
    theme: Map<String, Any?> = emptyMap(),
    initialComponents: List<A2uiComponentPayload> = emptyList(),
    initialData: Map<String, Any?> = emptyMap(),
    componentStubs: List<A2uiComponentStub> = emptyList()
): A2uiTestController
```

Creates a `https://developer.android.com/reference/kotlin/androidx/a2ui/compose/ui/testing/package-summary#A2uiTestController(androidx.a2ui.compose.ui.A2uiCatalog,kotlin.collections.Map,kotlin.collections.List,kotlin.collections.Map,kotlin.collections.List)` that can be used to drive tests.

```kotlin
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.compose.foundation.text.BasicText
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.v2.runComposeUiTest

runComposeUiTest {
    val titleProp = A2uiProperty.string("title")
    val rootStub =
        A2uiComponentStub.withId("root") { props, modifier ->
            val title = props[titleProp] ?: "Initial Title"
            BasicText(title, modifier = modifier.testTag("root_tag"))
        }

    // Initialize the controller with catalog and stubs
    val controller =
        A2uiTestController(
            catalog = A2uiCatalog("test_catalog", emptyList()),
            initialComponents = listOf(A2uiComponentPayload("root")),
            componentStubs = listOf(rootStub),
        )

    // Start message processing and initialize a surface model
    val surface = controller.start()

    setContent { A2uiTestSurface(surface = surface) }

    onNodeWithText("Initial Title").assertIsDisplayed()

    // Simulate an agent pushing an incremental property update to the component
    controller.updateComponent(id = "root", properties = mapOf("title" to "Updated Title"))
    // Suspend until the update components message is fully processed
    controller.waitForIdle()

    onNodeWithText("Updated Title").assertIsDisplayed()
}
```

| Parameters |
|---|---|
| `catalog: https://developer.android.com/reference/kotlin/androidx/a2ui/compose/ui/A2uiCatalog` | The `https://developer.android.com/reference/kotlin/androidx/a2ui/compose/ui/A2uiCatalog` under test. |
| `theme: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.collections/-map/index.html<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html, https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html?> = emptyMap()` | Simulated theme overrides (e.g., `primaryColor`) from the agent. |
| `initialComponents: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.collections/-list/index.html<https://developer.android.com/reference/kotlin/androidx/a2ui/model/protocol/A2uiComponentPayload> = emptyList()` | A list of `https://developer.android.com/reference/kotlin/androidx/a2ui/model/protocol/A2uiComponentPayload`s used to initialize the UI hierarchy. |
| `initialData: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.collections/-map/index.html<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html, https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html?> = emptyMap()` | The initial data tree injected into the data model. |
| `componentStubs: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.collections/-list/index.html<https://developer.android.com/reference/kotlin/androidx/a2ui/compose/ui/testing/A2uiComponentStub> = emptyList()` | A List of component stubs to override or append to the catalog. |

| Returns |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/a2ui/compose/ui/testing/A2uiTestController` | An unstarted `https://developer.android.com/reference/kotlin/androidx/a2ui/compose/ui/testing/package-summary#A2uiTestController(androidx.a2ui.compose.ui.A2uiCatalog,kotlin.collections.Map,kotlin.collections.List,kotlin.collections.Map,kotlin.collections.List)`. |

## Extension functions

### A2uiTestController.getData

Artifact: [androidx.a2ui.compose:compose-ui-testing](https://developer.android.com/jetpack/androidx/releases/a2ui-compose) [View Source](https://cs.android.com/search?q=file:androidx/a2ui/compose/ui/testing/A2uiTestController.kt+function:getData)

```
inline fun <T : Any?> A2uiTestController.getData(path: String): T?
```

Reads a value from the underlying data model at the specified JSON pointer path and casts it to the requested type `https://developer.android.com/reference/kotlin/androidx/a2ui/compose/ui/testing/package-summary#(androidx.a2ui.compose.ui.testing.A2uiTestController).getData(kotlin.String)`.

```kotlin
import androidx.a2ui.compose.ui.A2uiCatalog
import androidx.a2ui.compose.ui.testing.A2uiTestController
import androidx.a2ui.compose.ui.testing.getData
import androidx.compose.ui.test.v2.runComposeUiTest

runComposeUiTest {
    val controller =
        A2uiTestController(
            catalog = A2uiCatalog("test_catalog", emptyList()),
            initialData = mapOf("user" to mapOf("name" to "Alice")),
        )
    controller.start()

    // Read typed data from the controller's underlying data model
    val initialName: String? = controller.getData("/user/name")
    assertThat(initialName).isEqualTo("Alice")

    // Simulate the agent sending a data layer update
    controller.updateData("/user/name", "Bob")
    controller.waitForIdle()

    val updatedName: String? = controller.getData("/user/name")
    assertThat(updatedName).isEqualTo("Bob")
}
```

| Parameters |
|---|---|
| `path: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html` | The JSON pointer path to read (e.g., `"/user/name"`). |

| Returns |
|---|---|
| `T?` | The data model value cast to `https://developer.android.com/reference/kotlin/androidx/a2ui/compose/ui/testing/package-summary#(androidx.a2ui.compose.ui.testing.A2uiTestController).getData(kotlin.String)`, or `null` if the path does not exist. |

| Throws |
|---|---|
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-class-cast-exception/index.html` | if the value at `https://developer.android.com/reference/kotlin/androidx/a2ui/compose/ui/testing/package-summary#(androidx.a2ui.compose.ui.testing.A2uiTestController).getData(kotlin.String)` cannot be cast to `https://developer.android.com/reference/kotlin/androidx/a2ui/compose/ui/testing/package-summary#(androidx.a2ui.compose.ui.testing.A2uiTestController).getData(kotlin.String)`. |