Skip to content

Compose stops recomposing in tests #326

@vRallev

Description

@vRallev

In a weird combination of StateFlow, backgroundScope, UnconfinedTestDispatcher, collectAsState() and the Immediate recomposition mode the Compose runtime stops recomposing and Flows produced by Molecule stop sending events.

This test passes:

    @Test
    fun `something breaks`() = runTest {
        val _strings = MutableStateFlow("one")
        val strings: Flow<String> = _strings

        val molecule = (backgroundScope + UnconfinedTestDispatcher(testScheduler)).launchMolecule(RecompositionMode.Immediate) {
            val string by strings.collectAsState("one")
            string
        }

        molecule.test {
            assertThat(awaitItem()).isEqualTo("one")

            _strings.value = "two"
            assertThat(awaitItem()).isEqualTo("two")

            _strings.value = "three"
            assertThat(awaitItem()).isEqualTo("three")
        }
    }

If I change the initial value to something else such as collectAsState("abc"), then only "one" from the StateFlow is emitted but no other value anymore even though the StateFlow value changes. The composable function only recomposes when the initial value of the StateFlow and the collectAsState function are equal. This seems to be the bug.

Changing the flow to a MutableSharedFlow fixes the issue, because there’s no default value. Removing the UnconfinedTestDispatcher also fixes the issue. In this case it emits the initial value from collectAsState first, then the default value from the StateFlow and then all other changes. Using the same initial values also resolves the bug (the problem here is that StateFlow is an implementation detail of the underlying API, this example is simplified). It only breaks when the initial values are different.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions