class TasksViewModel( private val tasksRepository: TasksRepository ) : ViewModel() {
// Rest of class
}
class TaskViewModelFactory(
private val tasksRepository: TasksRepository
) : ViewModelProvider.NewInstanceFactory() {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return (TasksViewModel(tasksRepository) as T)
}
}
private val viewModel by viewModels<TasksViewModel> {
TasksViewModelFactory(DefaultTasksRepository.getRepository(requireActivity().application))
}
TasksViewModel 에서 FakeTasksRepository 만들어서 테스트 하는 법
class TasksViewModelTest{
private lateinit var fakeTasksRepository: FakeTestRepository
private lateinit var tasksViewModel: TasksViewModel
@Before
fun setUpViewModel() {
1. FakeTasksRepository 생성
fakeTasksRepository = FakeTestRepository()
val task1 = Task("Title1", "Description1")
val task2 = Task("Title2", "Description2", true)
val task3 = Task("Title3", "Description3", true)
tasksRepository.addTasks(task1, task2, task3)
//There's no need to use the delegate property or a ViewModelProvider,
// you can just directly construct the ViewModel in unit tests.
2. FakeTasksRepository를 주입한 TasksViewModel 생성
tasksViewModel = TasksViewModel(fakeTasksRepository)
}
}
FakeTasksRepository 만드는 법
DefaultTasksRepository
(원래 repository)에서 TaskRepository interface 추출DefaultTasksRepository
와 테스트용 FakeTestRepository
둘다 TaskRepository implementation하도록 설정위에서 viewModel에 fakeRepository를 넣는것 까진 했다.
따라서 viewModel 로컬 테스트는 가능.
그런데 Fragment를 테스트 하려니까, fragment 내부에서 viewModel을 만들고 있었다.
fragment는 직접 생성하지 않기 때문에 fragment 생성자에 viewModel을 주입 받을 수 없다.
그래서 serviceLocator 이라는 것을 사용한다.
그러면, fragment 테스트 클래스를 만들어서, fakeRepository ( 혹은 fakeRepository를 생성자로 가지는 viewModel)을 만들 수 있다.