Skip to content

Storage Test

WooSeok Suh edited this page Jul 20, 2021 · 2 revisions

2021-07-16

by Seok

Step.1

StorageType protocol을 활용한 Mock객체 Test

  • Unit Test파일추가
  • test project에 라이브러리 추가 (RxSwift, RxCocoa...)

Step.2

목 객체 생성

  • 함수 호출 여부 판단을 위해 callCount 프로퍼티 생성
  • 그 외 해당 protocol에 필요한 default implementation 추가
  • 메서드 정상동작 확인을 위한 기본 프로퍼티 추가
class MockStorage: NSObject, ItemStorageType {
    
    var availableMoenyMethodCallCount = 0
    var raiseLevelupMethodCallCount = 0
    var raiseMoneyMethodCallCount = 0
    var updateMethodCallCount = 0
    var createdMethodCallCount = 0
    
    private var myMoney = 1_000
    private lazy var moneyStatus = BehaviorSubject<Int>(value: myMoney)
    
    private var items = [Unit(info: .cPlusPlus, level: 1)]
    private lazy var store = BehaviorSubject<[Unit]>(value: items)
    
    // Default Implementation
    @discardableResult
    func availableMoeny() -> Observable<Int> {
        availableMoenyMethodCallCount+=1
        return moneyStatus
    }
    
    @discardableResult
    func itemList() -> [Unit] {
        return items
    }
    
    @discardableResult
    func create(item: Unit) -> Observable<Unit> {
        createdMethodCallCount += 1
        items.append(item)
        store.onNext(items)
        return Observable.just(item)
    }
    
    @discardableResult
    func list() -> Observable<[Unit]> {
        return store
    }
    
    @discardableResult
    func update(previous: Unit, new: Unit) -> Observable<Unit> {
        updateMethodCallCount += 1
        if let index = items.firstIndex(where: { $0 == previous}) {
            items.remove(at: index)
            items.insert(new, at: index)
        }
        store.onNext(items)
        return Observable.just(new)
    }
    
    @discardableResult
    func raiseLevel(to unit: Unit, using money: Int) -> Unit {
        raiseLevelupMethodCallCount += 1
        let new = Unit(original: unit, level: unit.level+1)
        update(previous: unit, new: new)
        myMoney -= money
        moneyStatus.onNext(myMoney)
        return new
    }
    
    func raiseMoney(by money: Int) {
        raiseMoneyMethodCallCount += 1
        myMoney += money
        moneyStatus.onNext(myMoney)
    }
}

Step.3

Verify 메서드 추가를 통한 테스트 실행

  • vefify메서드는 목객체 내부에서 생성
  • 테스트 객체에서 호출하여 결과 확인
import XCTest
import RxSwift
import RxCocoa
import NSObject_Rx

class StorageTest: XCTestCase {
    
    private var mockStorage: MockStorage!
    private var disposeBag: DisposeBag!
    
    override func setUpWithError() throws {
        mockStorage = MockStorage()
        disposeBag = DisposeBag()
    }

    override func tearDownWithError() throws {
    }

    func test_ShouldRaiseMoney() {
        mockStorage.verifyMoneyMethod(get: 1_000)
    }

    func test_ShouldRaiseLevel() {
        let unit = Unit(info: .cPlusPlus, level: 2)
        let requiredMoney = unit.level * 100
        mockStorage.verifyLevelupMethod(to: unit, using: requiredMoney)
    }
    
    func test_ShouldCreate() {
        let unit = Unit(info: .cSharp, level: 1)
        mockStorage.verifyCreatMethod(unit: unit)
    }
}
// Test
func verifyMoneyMethod(get money: Int) {
    availableMoeny()
    XCTAssertEqual(availableMoenyMethodCallCount, 1)
    raiseMoney(by: money)
    XCTAssertEqual(raiseMoneyMethodCallCount, 1)
    XCTAssertEqual(myMoney, 2_000)
}
    
func verifyLevelupMethod(to unit: Unit, using money: Int) {
    let updated = raiseLevel(to: unit, using: money)
    XCTAssertEqual(raiseLevelupMethodCallCount, 1)
    XCTAssertEqual(updated.level, 3)
    XCTAssertEqual(updateMethodCallCount, 1)
    XCTAssertEqual(800, myMoney)
}
    
func verifyCreatMethod(unit: Unit) {
    create(item: unit)
    XCTAssertEqual(createdMethodCallCount, 1)
    XCTAssertEqual(itemList().count, 2)
    XCTAssertEqual(itemList().last!, unit)
}
Clone this wiki locally