Checkout the getting started section to setup the test environment correctly.
This document outlines APIs for testing assertions about the component hierarchy. Litho's testing APIs are similar to the APIs of AssertJ and Hamcrest. If you have used the two before, this should feel very familiar. This guide will describe the APIs and its usage.
To demonstrate the usage of these APIs consider the following component that truncates the text passed and appends ellipsis.
As a quick side note; for trivial components like these it is often more appropriate to exploit the fact that these are pure functions that can be statically invoked. Whenever possible, test your business logic in isolation.
@RunWith(LithoTestRunner.class)to the top of the test class.
- Add a JUnit
- Add a check to ensure that tests are run in debug mode.
ComponentsConfiguration.IS_INTERNAL_BUILDmust be true.
The test class should look like the following:
LithoAssertions.assertThat(ComponentContext, Component)will create and mount the layout.
has(ComponentContext, Condition)tests if the component hierarchy passes the assertion of the Condition. This is a standard AssertJ API; checkout all the default APIs here.
subComponentWith(ComponentContext, Condition)is a utility method from Litho's testing APIs to compose Conditions together.
textEquals(String)is another utility method which creates a Condition that passes only for a Component of type
Textwhich has its text property set to the String argument.
subComponentWith(c, textEquals("Mr. Meeseeks")create a Condition which is exactly what it reads like; 'passes for a component of type Text with its text property set to "Mr. Meeseeks"'.
The following is a more complex composition of similar assertions
The above assertions are just for illustrative purposes. This is not a good test!
Consider a more complex LayoutSpec; it still has the same text truncation logic, but with some new UI elements; wrapping the Text in a Column and a Card.
The original test will start failing now.
The error messages should provide sufficient information to understand why the test failed. The error message prints out the component hierarchy, and the assertion that failed.
Text component was expected to be a direct descendant of
TruncatingComponent, but the
error message shows that the Text component is several levels below the TruncatingComponent.
This test can be fixed by using a different Condition API called
deepSubComponentWith. As the name
suggests this condition will test against all the components in the hierarchy, and not just the immediate
Find all the Component conditions in the JavaDoc here
Custom Conditions can be created by implementing the
which consists of a single method:
is a wrapper around a
Component with additional information about the component.
To test for the mere presence of a component of a certain type use the SubComponent.of API.
Consider a hypothetical LayoutSpec called
StoryComponentSpec, which composes a
LikersComponentSpec, and a
FeedbackComponentSpec. The following test can be used to assert the presence of
these components in the hierarchy.
Litho provides a bridge interface legacySubComponent
which enables using the
SubComponent.of API with the
subComponentWith APIs. It accepts a
SubComponent and works with both shallow and deep sub-component traversals. This is great
if you want to ensure that a component with a given set of props exists in the component tree.
To learn more, check out these resources: