junit

ViewModel에 의존하는 Composable을 테스트할 때 문제점 Composable은 기본적으로 State Hoisting을 통해 ViewModel에 직접 의존하지 않도록 만들어야 하지만, 최상위에 있는 Screen Composable은 상태값을 가지고 있는 ViewModel 객체에 의존해야 한다. *만약 State Hoisting이 무엇인지 모른다면 다음 두 개의 글을 참고하도록 하자. [Android Compose State] State Hoisting(상태 호이스팅) 패턴이란 무엇인가? Compose의 State 선언형 UI 프레임워크인 Compose는 Stateless함이 가장 큰 장점이다. UI에 대한 UI상태의 상호 의존성을 끊을 수 있다면 UI의 재사용성이 생기고, UI에 대한 테스트 ..
컴포즈의 UI 노드 구성 방법과 useUnmergedTree 안드로이드 UI 테스트를 작성하다 보면, 노드를 찾는 함수 안에 useUnmergedTree 인자가 들어가 있는 경우를 볼 수 있다. 이는 모든 onNode- 함수와 onAllNodes- 함수 안에 들어가 있는 것을 볼 수 있는데, 그만큼 중요한 인자임을 알 수 있다. 다음은 대표적인 두 개의 함수이다. 이 인자가 중요한 이유는 컴포즈가 UI 노드를 구성하는 방법과 연관되어 있다. xml 기반으로 작성되던 View 시스템에서는 각 View가 하나의 UI 노드가 되었지만, 컴포즈에서는 효율성을 위해 UI 노드를 하나로 합칠 수 있으면 합치는 방식(merge)을 취한다. 이를 통해 두 개의 Composable 혹은 세 개의 Composable이 하..
onNodeWithTag, onNodeWithText, onNodeWithContentDescription을 통해 UI 노드를 찾을 때의 한계점 onNodeWith- 구문을 사용해 UI 노드를 찾게 되면, 특정한 조건 하나만을 가진 UI 노드를 찾게 된다. 만약 같은 값을 공유하는 UI 노드가 있다면 둘 중 하나만이 선택되며, 그 둘을 구분할 수 있는 방법은 없다. 예를 들어 다음과 같이 같은 Smile이라는 이름을 가진 EmojiText Composable이 두 개 있다고 해보자. class OnNodeTest { @get:Rule val composeRule = createComposeRule() @Test fun onNodeWithProblem() { // Given var isSecondSmile..
every를 사용해 응답값을 설정할 때의 문제점 이전 글에서 다루었던 UserProfileFetcher이 리모트 저장소로부터 데이터를 가져오는 I/O 작업을 한다고 가정하고, 함수를 모두 다음과 같이 일시 중단 함수로 바꿔보자. class UserProfileFetcher( private val userRepository: UserRepository, ) { suspend fun getUserProfileById(id: String): UserProfile { return UserProfile( id = id, name = userRepository.getNameByUserId(id) ) } } interface UserRepository { suspend fun saveUserName(id: Strin..
Dummy란 무엇인가? Test Doubles에서 Dummy란 어떤 함수를 호출하든 응답값으로 빈 값을 주는 객체를 뜻한다. 이러한 Dummy는 반환값이 필요없는 객체의 반환값을 설정하기 위해 사용한다. 하지만, 순수한 의미의 Dummy는 응답값이 설정되는 순간부터는 Stub이 되기 때문에 사용처가 한정된다. 테스트를 위한 환경 설정 이 글에서는 ManyGetRepository를 주입 받는 ManyGetUseCase를 테스트 한다. class ManyGetUseCase( private val manyGetRepository: ManyGetRepository ) { fun callGet(int: Int): Int = when (int) { 0 -> manyGetRepository.getA() 1 -> ma..
Dev.Cho
'junit' 태그의 글 목록