Kevin Worth
03/16/2023, 2:53 PMimport androidx.lifecycle.viewmodel.compose.viewModel
...
@Composable
fun PrimaryScreen(viewModel: PrimaryViewModel = viewModel()) {...}
class PrimaryViewModel @Inject constructor(
private val jokeRepository: JokeRepository
) : ViewModel() {...}
// app/src/main/java/com/example/jokes/data/di/DataModule.kt
@Module
@InstallIn(SingletonComponent::class)
interface DataModule {
@Singleton
@Binds
fun bindsJokeRepository(
jokeRepository: DefaultJokeRepository
): JokeRepository
...
}
// app/src/androidTest/java/com/example/jokes/testdi/TestDataModule.kt
@Module
@TestInstallIn(
components = [SingletonComponent::class],
replaces = [DataModule::class]
)
interface FakeDataModule {
@Binds
abstract fun bindRepository(
fakeRepository: FakeJokeRepository
): JokeRepository
...
}
@RunWith(AndroidJUnit4::class)
@HiltAndroidTest
class PrimaryScreenTest {
var hiltRule = HiltAndroidRule(this)
val composeTestRule = createAndroidComposeRule<ComponentActivity>()
@get:Rule
val rule: RuleChain = RuleChain
.outerRule(hiltRule)
.around(composeTestRule)
@Before
fun setup() {
hiltRule.inject()
composeTestRule.setContent {
PrimaryScreen() // Doesn't work
// PrimaryScreen(viewModel()) // Also doesn't work
}
}
When I try to run my tests I get:
java.lang.RuntimeException: Cannot create an instance of class com.example.jokes.ui.joke.PrimaryViewModel
...
Caused by: java.lang.NoSuchMethodException: com.example.jokes.ui.joke.PrimaryViewModel.<init> []
Any ideas from anyone?- fun PrimaryScreen(viewModel: PrimaryViewModel = viewModel()) {
+ fun PrimaryScreen() {
+ val viewModel: PrimaryViewModel = viewModel()
Now I wonder if anyone knows why… (again, with the key point being, if it works in the production code, why not in instrumented tests…)