# AppFunctionTestRule

Artifact: [androidx.appfunctions:appfunctions-testing](https://developer.android.com/jetpack/androidx/releases/appfunctions) [View Source](https://cs.android.com/search?q=file:androidx/appfunctions/testing/AppFunctionTestRule.kt+class:androidx.appfunctions.testing.AppFunctionTestRule) Added in [1.0.0-rc01](https://developer.android.com/jetpack/androidx/releases/appfunctions#1.0.0-rc01)

*** ** * ** ***


```
@RequiresApi(value = 36)
class AppFunctionTestRule : TestRule
```

<br />

*** ** * ** ***

A JUnit TestRule for setting up an environment to exercise AppFunction APIs in unit or Robolectric tests.

Prefer real system-level testing where possible. This rule is intended only for local tests that simulate cross-app interactions via AppFunctions.

### Setup

1. Apply the `appfunctions-compiler` annotation processor to the test configuration:

   ```kotlin
    dependencies {
        // ...
        kspTest("androidx.appfunctions:appfunctions-compiler:xx.xx.xx")
    }
   ```
2. Define the service entry point class with `@AppFunctionServiceEntryPoint`. This is either an existing service in the app under test or a test service created specifically for agent integration testing. See `https://developer.android.com/reference/kotlin/androidx/appfunctions/AppFunctionServiceEntryPoint` for set-up instructions.  
   **Note:** If a service's enabled state changes dynamically via `https://developer.android.com/reference/android/content/pm/PackageManager.html#setComponentEnabledSetting(android.content.ComponentName, int, int)`, call `https://developer.android.com/reference/kotlin/androidx/appfunctions/testing/AppFunctionTestRule#reloadAppFunctions()` to reload its functions.

### Example:

```kotlin
package com.example.appfunctions

class ExampleFunctionsTest {
    @get:Rule val appFunctionTestRule = AppFunctionTestRule(context)
    private val appFunctionManager = appFunctionTestRule.getAppFunctionManager()

    @Test
    fun addFunction_returnsCorrectSum() = runBlocking {
        val appFunctionName = AppFunctionName(
            packageName = "com.example.appfunctions",
            functionIdentifier = "com.example.pkg.TestAppFunctionService#addFunction"
        )
        val appFunctions = appFunctionManager.searchAppFunctions(
            AppFunctionSearchSpec(functionNames = setOf(appFunctionName))
        )
        val addFunctionMetadata = appFunctions.single()

        val response = appFunctionManager.executeAppFunction(
            ExecuteAppFunctionRequest(
                targetPackageName = context.packageName,
                functionIdentifier = addFunctionMetadata.id,
                functionParameters = AppFunctionData.Builder(
                    addFunctionMetadata.parameters,
                    addFunctionMetadata.components
                )
                    .setLong("a", 2)
                    .setLong("b", 3)
                    .build()
            )
        )

        // Assert on returned response.
    }
}
```

## Summary

| ### Public constructors |
|---|
| `https://developer.android.com/reference/kotlin/androidx/appfunctions/testing/AppFunctionTestRule#AppFunctionTestRule(android.content.Context)(context: https://developer.android.com/reference/android/content/Context.html)` |

| ### Public functions |
|---|---|
| `open https://junit.org/junit4/javadoc/latest/org/junit/runners/model/Statement.html` | `https://developer.android.com/reference/kotlin/androidx/appfunctions/testing/AppFunctionTestRule#apply(org.junit.runners.model.Statement,org.junit.runner.Description)(base: https://junit.org/junit4/javadoc/latest/org/junit/runners/model/Statement.html?, description: https://junit.org/junit4/javadoc/latest/org/junit/runner/Description.html?)` |
| `https://developer.android.com/reference/kotlin/androidx/appfunctions/AppFunctionManager` | `https://developer.android.com/reference/kotlin/androidx/appfunctions/testing/AppFunctionTestRule#getAppFunctionManager()()` Returns an `https://developer.android.com/reference/kotlin/androidx/appfunctions/AppFunctionManager` instance for interacting with AppFunctions registered via the test rule. |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `@https://developer.android.com/reference/kotlin/androidx/appfunctions/ExperimentalAppFunctionsApi https://developer.android.com/reference/kotlin/androidx/appfunctions/testing/AppFunctionTestRule#reloadAppFunctions()()` Triggers AppFunction indexing. |

## Public constructors

### AppFunctionTestRule

Added in [1.0.0-rc01](https://developer.android.com/jetpack/androidx/releases/appfunctions#1.0.0-rc01)

```
AppFunctionTestRule(context: Context)
```

## Public functions

### apply

Added in [1.0.0-rc01](https://developer.android.com/jetpack/androidx/releases/appfunctions#1.0.0-rc01)

```
open fun apply(base: Statement?, description: Description?): Statement
```

### getAppFunctionManager

Added in [1.0.0-rc01](https://developer.android.com/jetpack/androidx/releases/appfunctions#1.0.0-rc01)

```
fun getAppFunctionManager(): AppFunctionManager
```

Returns an `https://developer.android.com/reference/kotlin/androidx/appfunctions/AppFunctionManager` instance for interacting with AppFunctions registered via the test rule.

### reloadAppFunctions

Added in [1.0.0-rc01](https://developer.android.com/jetpack/androidx/releases/appfunctions#1.0.0-rc01)

```
@ExperimentalAppFunctionsApi
fun reloadAppFunctions(): Unit
```

Triggers AppFunction indexing.

Call this function after updating service component state with `https://developer.android.com/reference/android/content/pm/PackageManager.html#setComponentEnabledSetting(android.content.ComponentName, int, int)` to re-index available functions.

Once returned, the AppFunctions indexation is guaranteed to be finished. If any static metadata has changed, active observers of `https://developer.android.com/reference/kotlin/androidx/appfunctions/AppFunctionManager#observeAppFunctions()` will be notified of changes. `https://developer.android.com/reference/kotlin/androidx/appfunctions/AppFunctionManager#searchAppFunctions(androidx.appfunctions.AppFunctionSearchSpec)` will return the updated metadata, if queried, and `https://developer.android.com/reference/kotlin/androidx/appfunctions/AppFunctionManager#executeAppFunction(androidx.appfunctions.ExecuteAppFunctionRequest)` will use the updated metadata.

### Example: Enabling a Disabled Service Component

```kotlin
// Target the generated service specified by serviceName in @AppFunctionServiceEntryPoint.
val componentName = ComponentName(
    context,
    "com.example.appfunctions.TestAppFunctionService"
)
context.packageManager.setComponentEnabledSetting(
    componentName,
    PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
    PackageManager.DONT_KILL_APP
)
// Re-index to discover updated service functions.
appFunctionTestRule.reloadAppFunctions()
```