Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TEST] My Page Unit Test (#199) #202

Merged
merged 13 commits into from
Dec 4, 2023
Merged

[TEST] My Page Unit Test (#199) #202

merged 13 commits into from
Dec 4, 2023

Conversation

cchanmi
Copy link
Member

@cchanmi cchanmi commented Dec 3, 2023

🌱 작업한 내용

  • my page network와 관련된 service unit test
  • my page view model unit test
  • my page view controller unit test

🌱 PR Point

my page network와 관련된 service unit test

  • 실제 api를 호출하기에는 시간이 많이 걸리고, 네트워크 환경에 따라 통신이 실패할 수 있기 때문에 기존의 urlSession을 대신한 urlSessionStub를 이용하여 service 테스트를 진행했습니다.

진행한 테스트

  1. 마이페이지 유저 프로필 API 호출시 데이터를 잘 받아오는지 테스트했습니다.

my page view model unit test

  • viewModel에서 manager에 대한 로직을 검증하기 때문에, 기존 manager가 아닌 managerStu를 사용하여 테스트를 진행했습니다.
final class MyPageManagerStub: MyPageManager {
    
    var appData: BadgeProfileAppData?
    var resignResult: Bool?
    
    func getMyPage() async throws -> LionHeart_iOS.BadgeProfileAppData {
        guard let appData = appData else { throw NetworkError.badCasting }
        return appData
    }
    
    func resignUser() async throws {
        guard let _ = resignResult else { throw NetworkError.clientError(code: "V001", message: "탈퇴 실패") }
    }
    
    func logout(token: LionHeart_iOS.UserDefaultToken) async throws {
        print("로그아웃 성공")
    }
}

‼️ 추가로 의논할 부분이 있어서 viewModel 관련 내용은 여기까지 적고 낼 다시 추가해서 수정하겟습니다

진행한 테스트

  1. viewWillAppear 성공시 appData가 잘 전달되었는지
  2. viewWillAppear 실패시 error와 빈 empty data가 잘 전달되었는지
  3. resignButtonTapped 호출시 회원탈퇴 후, 올바른 flowType이 전달되었는지
  4. backButtonTapped 호출시 올바른 flowType이 전달되었는지

my page view controller unit test

  • viewConroller가 ViewModel를 주입받고 있었고, 행동과 상태를 검증해 주는 viewModelSpy로부터 받은 데이터를 viewcontroller의 ui component에 잘 반영되는지를 테스트했습니다.
final class MyPageViewModelSpy: MyPageViewModel {
    
    let isBackButtonTapped = PassthroughSubject<Bool, Never>()
    let isResignButtonTapped = PassthroughSubject<Bool, Never>()
    let isViewWillAppearSubject = PassthroughSubject<Bool, Never>()
    
    var myPageModel = MyPageModel.empty
    var cancelBag = Set<AnyCancellable>()
    
    func transform(input: LionHeart_iOS.MyPageViewModelInput) -> LionHeart_iOS.MyPageViewModelOutput {
        input.viewWillAppearSubject
            .sink { [weak self] _ in
                self?.isViewWillAppearSubject.send(true)
            }
            .store(in: &cancelBag)
        
        input.resignButtonTapped
            .sink { [weak self] _ in
                self?.isResignButtonTapped.send(true)
            }
            .store(in: &cancelBag)
        
        input.backButtonTapped
            .sink { [weak self] _ in
                self?.isBackButtonTapped.send(true)
            }
            .store(in: &cancelBag)
        
        let output = Just(myPageModel).eraseToAnyPublisher()
        
        return Output(viewWillAppearSubject: output)
    }
}
  • data가 들어왔을 때, 해당 component의 image 이름, label의 text값이 의도된대로 반영되었는지를 테스트했습니다.
    func test_데이터바인딩성공() {
        // given
        let viewController = MyPageViewController(viewModel: self.viewModel)
        let badgeData = BadgeProfileAppData(badgeImage: "LEVEL_ONE", nickname: "test nickname", isAlarm: "on")
        self.viewModel.myPageModel = MyPageModel(profileData: badgeData, appSettingData: [], customerServiceData: [])
        
        // when
        viewController.loadViewIfNeeded()
        let headerView = viewController.headerView
        viewController.setTableViewHeader(badgeData)
        
        // then
        XCTAssertEqual(headerView.badgeImageView.image, BadgeLevel(rawValue: "LEVEL_ONE")?.badgeImage)
        XCTAssertEqual(headerView.profileLabel.text, """
                                                     test nickname아빠님,
                                                     오늘도 멋진 아빠가 되어 볼까요?
                                                     """)
    }

진행한 테스트

  1. viewWillAppear 이벤트가 ViewModel에 잘 전달되었는지
  2. resinButtonTapped 이벤트가 ViewModel에 잘 전달되었는지
  3. backButtonTapped 이벤트가 ViewModel에 잘 전달되었는지
  4. 전달받은 data가 ui component에 의도된대로 바인딩되었는지

📸 스크린샷

coverage 진척도

  • ViewModel
image
  • ViewController
image

‼️ 머지는 내일 같이 하겠습니다! xctestplan 때문에 혹시라도 좀 크게 충돌 날까봐요

📮 관련 이슈

@cchanmi cchanmi added 🦁찬미 찬미's 🧪Test 테스트 labels Dec 3, 2023
@cchanmi cchanmi added this to the 🦁3차 Refactor🦁 milestone Dec 3, 2023
@cchanmi cchanmi self-assigned this Dec 3, 2023
XCTAssertTrue(isEventOccured!)
}

func test_데이터바인딩성공() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

메서드명을 좀더 자세하게 적는게 좋을거같아용

Suggested change
func test_데이터바인딩성공() {
func test_myPage데이터가_제대로_들어왔을때_UI에_반영이_잘_되는지() {

Comment on lines 12 to 15
final class MyPageManagerStub: MyPageManager {

var appData: BadgeProfileAppData?
var resignResult: Bool?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

단순히 데이터를 return해주는게 아닌 appData가 잘 들어왔는지, resignUserResult로인해 함수호출이 잘되었는지까지 확인하는거면 Stub보다는 spy가 맞을거같습니다

Copy link
Contributor

@kimscastle kimscastle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

반영사항 확인부탁드립니다~

@cchanmi cchanmi merged commit e06ae23 into main Dec 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🦁찬미 찬미's 🧪Test 테스트
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[TEST] MyPage Unit Test
2 participants