简体   繁体   中英

How to properly test if selected theme is light mode or dark mode

I am new to testing and trying to test this in my fragment:

When user clicks an icon, check the selected theme first (using live data).

  • If the selected theme is light, change to dark mode and assert that it is dark mode:
  • Else, if the selected theme is dark, change to light mode and assert that it is light mode:

HomeFragmentTest.kt

@HiltAndroidTest
@UninstallModules(StorageModule::class)
class HomeFragmentTest{

@get:Rule(order = 0)
var hiltAndroidRule = HiltAndroidRule(this)

@get:Rule(order = 1)
var instantTaskExecutorRule = InstantTaskExecutorRule()

@Inject
lateinit var dataStorage: DataStorage

@Before
fun setUp(){
    hiltAndroidRule.inject()
}

private lateinit var storageViewModel: StorageViewModel
private var selectedTheme: String? = null

@Test
fun testThatThemeIsChangedWhenClicked(){
    storageViewModel = StorageViewModel(dataStorage)
    launchFragmentInHiltContainer<HomeFragment> {
       selectedTheme = storageViewModel.selectedTheme.getOrAwaitValue()
    }

    onView(withId(R.id.ic_theme_mode)).perform(click())

    if (selectedTheme == "light"){
        runOnUiThread {
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
            storageViewModel.changeSelectedTheme("dark")
        }
        assertThat(selectedTheme).isEqualTo("dark")
    }

    else if (selectedTheme == "dark"){
        runOnUiThread {
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
            storageViewModel.changeSelectedTheme("light")
        }
        assertThat(selectedTheme).isEqualTo("light")
    }
 }
}

StorageViewModel.kt

@HiltViewModel
class StorageViewModel @Inject constructor(private val dataStorage: DataStorage) 
: ViewModel()  {

val selectedTheme = dataStorage.selectedTheme().asLiveData()
fun changeSelectedTheme(theme: String){
    viewModelScope.launch {
        dataStorage.setSelectedTheme(theme)
    }
 }
}

It seems that for some reasons, " storageViewModel.changeSelectedTheme("dark") " doesn't work.

The tests fails, with the error:

expected: dark but was: light at HomeFragmentTest.testThatThemeIsChangedWhenClicked(HomeFragmentTest.kt:70)

When I run again, I get:

expected: light but was: dark at HomeFragmentTest.testThatThemeIsChangedWhenClicked(HomeFragmentTest.kt:76)

runOnUiThread posts a runnable to the event queue of the main thread, and the code gets executed later - so your check happens before the theme is actually changed. (Unless you're already on the main thread, in which case you wouldn't need runOnUiThread in the first place)

You might want to use the UiThreadTest annotation so the whole test runs on the main thread, then you don't need to worry about async handling

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM