|  | # Adding custom Truth subjects | 
|  |  | 
|  | [TOC] | 
|  |  | 
|  | ## Custom truth subjects | 
|  |  | 
|  | Every subject class should extend | 
|  | [Subject](https://truth.dev/api/latest/com/google/common/truth/Subject.html) and | 
|  | follow the naming schema `[ClassUnderTest]Subject`. The Subject must also have a | 
|  | constructor that accepts | 
|  | [FailureMetadata](https://truth.dev/api/latest/com/google/common/truth/FailureMetadata.html) | 
|  | and a reference to the object under test, which are both passed to the | 
|  | superclass. | 
|  |  | 
|  | ```kotlin | 
|  | class NavControllerSubject private constructor( | 
|  | metadata: FailureMetadata, | 
|  | private val actual: NavController | 
|  | ) : Subject(metadata, actual) { } | 
|  | ``` | 
|  |  | 
|  | ### Subject factory | 
|  |  | 
|  | The Subject class should also contain two static fields; a | 
|  | [Subject Factory](https://truth.dev/api/latest/com/google/common/truth/Subject.Factory.html) | 
|  | and an`assertThat()` shortcut method. | 
|  |  | 
|  | A subject Factory provides most of the functionality of the Subject by allowing | 
|  | users to perform all operations provided in the Subject class by passing this | 
|  | factory to `about()` methods. E.g: | 
|  |  | 
|  | `assertAbout(navControllers()).that(navController).isGraph(x)` where `isGraph()` | 
|  | is a method defined in the Subject class. | 
|  |  | 
|  | The assertThat() shortcut method simply provides a shorthand method for making | 
|  | assertions about the Subject without needing a reference to the subject factory. | 
|  | i.e., rather than using | 
|  | `assertAbout(navControllers()).that(navController).isGraph(x)` users can simply | 
|  | use`assertThat(navController).isGraph(x)`. | 
|  |  | 
|  | ```kotlin | 
|  | companion object { | 
|  | fun navControllers(): Factory<NavControllerSubject, NavController> = | 
|  | Factory<NavControllerSubject, NavController> { metadata, actual -> | 
|  | NavControllerSubject(metadata, actual) | 
|  | } | 
|  |  | 
|  | @JvmStatic | 
|  | fun assertThat(actual: NavController): NavControllerSubject { | 
|  | return assertAbout(navControllers()).that(actual) | 
|  | } | 
|  | } | 
|  | ``` | 
|  |  | 
|  | ### Assertion methods | 
|  |  | 
|  | When creating assertion methods for your custom Subject the names of these | 
|  | methods should follow the | 
|  | [Truth naming convention](https://truth.dev/faq#assertion-naming). | 
|  |  | 
|  | To create assertion methods it is necessary to either delegate to an existing | 
|  | assertion method by using `Subject.check()` or to provide your own failure | 
|  | strategy by using`failWithActual()` or `failWithoutActual()`. | 
|  |  | 
|  | When using `failWithActual()` the error message will display the`toString()` | 
|  | value of the Subject object. Additional information can be added to these error | 
|  | messages by using `fact(key, value)` or `simpleFact(value)` where `fact()` will | 
|  | be output as a colon separated key, value pair. | 
|  |  | 
|  | ```kotlin | 
|  | fun isGraph(@IdRes navGraph: Int) { | 
|  | check("graph()").that(actual.graph.id).isEqualTo(navGraph) | 
|  | } | 
|  |  | 
|  | // Sample Failure Message | 
|  | value of          : navController.graph() | 
|  | expected          : 29340 | 
|  | but was           : 10394 | 
|  | navController was : {actual.toString() value} | 
|  | ``` | 
|  |  | 
|  | ```kotlin | 
|  | fun isGraph(@IdRes navGraph: Int) { | 
|  | val actualGraph = actual.graph.id | 
|  | if (actualGraph != navGraph) { | 
|  | failWithoutActual( | 
|  | fact("expected id", navGraph.toString()), | 
|  | fact("but was", actualGraph.toString()), | 
|  | fact("current graph is", actual.graph) | 
|  | ) | 
|  | } | 
|  | } | 
|  |  | 
|  | // Sample Failure Message | 
|  | expected id      : 29340 | 
|  | but was          : 10394 | 
|  | current graph is : {actual.graph.toString() value} | 
|  | ``` | 
|  |  | 
|  | ## Testing | 
|  |  | 
|  | When testing expected successful assertions it is enough to simply call the | 
|  | assertion with verified successful actual and expected values. | 
|  |  | 
|  | ```kotlin | 
|  | private lateinit var navController: NavController | 
|  | @Before | 
|  | fun setUp() { | 
|  | navController = NavController( | 
|  | ApplicationProvider.getApplicationContext() | 
|  | ).apply { | 
|  | navigationProvider += TestNavigator() | 
|  | // R.navigation.testGraph == R.id.test_graph | 
|  | setGraph(R.navigation.test_graph) | 
|  | } | 
|  | } | 
|  |  | 
|  | @Test | 
|  | fun testGraph() { | 
|  | assertThat(navController).isGraph(R.id.test_graph) | 
|  | } | 
|  | ``` | 
|  |  | 
|  | To test that expected failure cases you should use the | 
|  | [assertThrows](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:testutils/testutils-truth/src/main/java/androidx/testutils/assertions.kt) | 
|  | function from the AndroidX testutils module. The assertions.kt file contains two | 
|  | assertThrows functions. The second method, which specifically returns a | 
|  | TruthFailureSubject, should be used since it allows for validating additional | 
|  | information about the FailureSubject, particularly that it contains specific | 
|  | fact messages. | 
|  |  | 
|  | ```kotlin | 
|  | @Test | 
|  | fun testGraphFailure() { | 
|  | with(assertThrows { | 
|  | assertThat(navController).isGraph(R.id.second_test_graph) | 
|  | }) { | 
|  | factValue("expected id").isEqualTo(R.id.second_test_graph.toString()) | 
|  | factValue("but was").isEqualTo(navController.graph.id.toString()) | 
|  | factValue("current graph is").isEqualTo(navController.graph.toString()) | 
|  | } | 
|  | } | 
|  | ``` | 
|  |  | 
|  | ## Helpful resources | 
|  |  | 
|  | [Truth extension points](https://truth.dev/extension.html) |