Archive/패캠(초격차)

part5 (ch6). KeywordNews XCTest 코드리뷰

lgvv 2022. 2. 17. 02:23

✅ 코드 리뷰는 언제나 포스팅과 함께한다.

이 부분은 다른 누군가가 볼 것 같지는 않고 나 혼자 쓰는 말이라서 더 편한데 곧 네이버 블로그에 일상이나 담아봐야겠다.

그래서 이런거 왜쓰냐면 내가 깃허브에 파일 따로 올려 정리하는게 나한테는 좋은 학습으로 다가오지 않아서, 블로그에 글을 올리면서 다시 보는게 더욱 좋더라

 

 

✅ 파일의 구조

테스트 코드 파일의 구조

 

✅ 만났던 문제 하나.

2022.02.15 - [project30-비공개] - [iOS] 🧑🏻‍💻 Xcode 기존 프로젝트에 XCTest 작성 파일 추가하기!

 

[iOS] 🧑🏻‍💻 Xcode 기존 프로젝트에 XCTest 작성 파일 추가하기!

✅ 에러에 대해서 알아보자. 🟠 Library not loaded: @rpath/XCTest.framework/XCTest Xcode 파일을 만들 때, test를 include하지 않고 만들었다가 이후에 테스트를 해야해서 테스트 코드 파일을 만들고 돌리..

rldd.tistory.com

이거 해결하다가 머리 터질뻔 ... ㅏㅎ .. 

 

 

✅ NewsListPresenterTest.swift

//
//  NewsListPresenterTest.swift
//  KeywordNews
//
//  Created by Hamlit Jason on 2022/02/09.
//

import XCTest
@testable import KeywordNews

class NewsListPresenterTest: XCTestCase {
   
    var sut: NewsListPresenter!
    
    var viewController: MockNewsListViewController!
    var newsSearchManager: MockNewsSearchManager!
    
    override func setUp() {
        super.setUp()
        
        viewController = MockNewsListViewController()
        newsSearchManager = MockNewsSearchManager()
        
        sut = NewsListPresenter(viewController: viewController, newsSearchManager: newsSearchManager)
    }
    
    override func tearDown() {
        // tearDown은 setUp의 반대 순서로 하는게 안전
        sut = nil
        
        newsSearchManager = nil
        viewController = nil
    }
    
    func test_viewDidLoad가_불려졌을때() {
        sut.viewDidLoad()
        
        XCTAssertTrue(viewController.isCalledSetupNavigationBar)
        XCTAssertTrue(viewController.isCalledSetupLayout)
    }
    
    func test_didCalledRefresh가_요청될때_request에_성공하면() {
        newsSearchManager.error = nil
        
        sut.didCalledRefresh()
        XCTAssertTrue(viewController.isCalledReloadTableView)
        XCTAssertTrue(viewController.isCalledEndRefreshing)
    }
    
    func test_didCalledRefresh가_요청될때_request에_실패하면() {
        newsSearchManager.error = NSError() as Error
        
        sut.didCalledRefresh()
        XCTAssertFalse(viewController.isCalledReloadTableView)
        XCTAssertFalse(viewController.isCalledEndRefreshing)
    }
}

에러 핸들링 하는 부분이 조금 특이한데, 매니저의 에러를 줄 수도 있꼬, 안줄 수도 있다. 

 

 

✅ MockNewsSearchManager.swift

//
//  MockNewsSearchManager.swift
//  KeywordNews
//
//  Created by Hamlit Jason on 2022/02/09.
//

import Foundation
@testable import KeywordNews

final class MockNewsSearchManager: NewsSearchManagerProtocol {
    var error: Error?
    var isCalledRequest = false

    func request(
        from keyword: String,
        start: Int,
        display: Int,
        completionHandler: @escaping ([News]) -> Void
    ) {
        isCalledRequest = true

        if error == nil {
            completionHandler([])
        }
    }
}

에러를 핸들링 할 수 있게끔 매니저를 만드는 모습이 특이했다.

그렇게 함으로써 컴프리션 핸들러를 다룬다니

 

 

✅ MockNewsListViewController.swift

//
//  MockNewsListViewController.swift
//  KeywordNews
//
//  Created by Hamlit Jason on 2022/02/09.
//

import XCTest
@testable import KeywordNews

final class MockNewsListViewController: NewsListProtocol {
    var isCalledSetupNavigationBar = false
    var isCalledSetupLayout = false
    var isCalledEndRefreshing = false
    var isCalledMoveToNewsWebViewController = false
    var isCalledReloadTableView = false


    func setupNavigationBar() {
        isCalledSetupNavigationBar = true
    }

    func setupLayout() {
        isCalledSetupLayout = true
    }

    func endRefreshing() {
        isCalledEndRefreshing = true
    }

    func moveToNewsWebViewController(with news: News) {
        isCalledMoveToNewsWebViewController = true
    }

    func reloadTableView() {
        isCalledReloadTableView = true
    }
}

 

테스트 코드는 진짜 엄청나게 열심히 공부해봐야겠다