# 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)
public final class AppFunctionTestRule implements 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:

   ```
    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/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/androidx/appfunctions/testing/AppFunctionTestRule#reloadAppFunctions()` to reload its functions.

### Example:

```
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/androidx/appfunctions/testing/AppFunctionTestRule#AppFunctionTestRule(android.content.Context)(@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/android/content/Context.html context)` |

| ### Public methods |
|---|---|
| `@https://developer.android.com/reference/androidx/annotation/NonNull https://junit.org/junit4/javadoc/latest/org/junit/runners/model/Statement.html` | `https://developer.android.com/reference/androidx/appfunctions/testing/AppFunctionTestRule#apply(org.junit.runners.model.Statement,org.junit.runner.Description)(https://junit.org/junit4/javadoc/latest/org/junit/runners/model/Statement.html base, https://junit.org/junit4/javadoc/latest/org/junit/runner/Description.html description)` |
| `final @https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/appfunctions/AppFunctionManager` | `https://developer.android.com/reference/androidx/appfunctions/testing/AppFunctionTestRule#getAppFunctionManager()()` Returns an `https://developer.android.com/reference/androidx/appfunctions/AppFunctionManager` instance for interacting with AppFunctions registered via the test rule. |
| `final void` | `@https://developer.android.com/reference/androidx/appfunctions/ExperimentalAppFunctionsApi https://developer.android.com/reference/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)

```
public AppFunctionTestRule(@NonNull Context context)
```

## Public methods

### apply

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

```
public @NonNull Statement apply(Statement base, Description description)
```

### getAppFunctionManager

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

```
public final @NonNull AppFunctionManager getAppFunctionManager()
```

Returns an `https://developer.android.com/reference/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
public final void reloadAppFunctions()
```

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/androidx/appfunctions/AppFunctionManager#observeAppFunctions()` will be notified of changes. `https://developer.android.com/reference/androidx/appfunctions/AppFunctionManager#searchAppFunctions(androidx.appfunctions.AppFunctionSearchSpec)` will return the updated metadata, if queried, and `https://developer.android.com/reference/androidx/appfunctions/AppFunctionManager#executeAppFunction(androidx.appfunctions.ExecuteAppFunctionRequest)` will use the updated metadata.

### Example: Enabling a Disabled Service Component

```
// 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()
```