1

So bin ich völlig neu zu testen und ich brauchte nur etwas Hilfe herauszufinden, zum Beispiel wie ich einen Test für jeden der drei Fälle in der Aufzählung des View-Modells schreiben würde (keine, dontSeeProvider, showAllProviders).Wie würde ich einen Test schreiben, um sicherzustellen, dass der UIbutton "Alle Provider anzeigen" angezeigt wird, wenn mehr als 12 oder mehr Einträge in der Tabellenansicht vorhanden sind?

enum ProvidersButtonType { 
case none, dontSeeProvider, showAllProviders 
} 

habe ich in der Lage, um herauszufinden, nicht wie ein Test für die Fälle „showAllProviders“ und „dontSeeProviders“ zu schreiben.

Dies ist die Ansicht Modell:

import RxSwift 
import RxCocoa 

struct TopProvidersPickerItem { 
let provider: MVPD 

let logoImage: Observable<UIImage> 

init(provider: MVPD, imageLoader: DecodableProviding) { 
    self.init(provider: provider, logoImage: imageLoader.image(fromURL: provider.logoUrl)) 
} 

init(provider: MVPD, logoImage: Observable<UIImage>) { 
    self.provider = provider 
    self.logoImage = logoImage.catchErrorJustReturn(UIImage()) 
} 
} 

enum ProvidersButtonType { 
case none, dontSeeProvider, showAllProviders 
} 

struct TopProvidersPickerViewModel { 
var caption: String { 
    return "Get access to more full episodes by signing in with your TV Provider" 
} 

let buttonType = Variable<ProvidersButtonType>(.none) 
let items: Observable<[TopProvidersPickerItem]> 
let selectedItem: PublishSubject<TopProvidersPickerItem> = PublishSubject() 
let showAllProvidersTrigger: PublishSubject<Void> = PublishSubject() 
let mvpdPicked: Observable<MVPD> 

init(topProviders: Observable<[MVPD]>, imageLoader: DecodableProviding) { 
    let items = topProviders.map({ mvpds in 
     return mvpds.map { mvpd in 
      TopProvidersPickerItem(provider: mvpd, imageLoader: imageLoader) 
     } 
    }) 
    self.init(items: items) 
} 

init(items: Observable<[TopProvidersPickerItem]>) { 
    self.items = items 
    mvpdPicked = selectedItem.map { $0.provider } 
    let buttonType = items.map { (array) -> ProvidersButtonType in 
     if array.count > 12 { 
      return .showAllProviders 
     } else { 
      return .dontSeeProvider 
     } 
    } 
    buttonType.bind(to: self.buttonType) 
} 

} 

Dies ist der View-Controller:

import UIKit 
import RxCocoa 
import RxSwift 

public class ProviderCollectionViewCell: UICollectionViewCell { 
    @IBOutlet public private(set) weak var imageView: UIImageView! 
} 

public class TopProvidersPickerViewController: UIViewController, 
ViewModelHolder { 
var viewModel: TopProvidersPickerViewModel! = nil 
private let bag = DisposeBag() 

@IBOutlet public private(set) weak var collectionView: UICollectionView! 
@IBOutlet public private(set) weak var captionLabel: UILabel! 
@IBOutlet weak var viewAllProvidersButton: UIButton! 

override public func viewDidLoad() { 
    super.viewDidLoad() 
    captionLabel.text = viewModel.caption 
    setupRx() 
} 

private func setupRx() { 
    viewModel.buttonType.asObservable().subscribe(onNext: { [button = self.viewAllProvidersButton] type in 
     button?.isHidden = false 

     switch type { 
     case .none: 
      button?.isHidden = true 
     case .dontSeeProvider: 
      button?.setTitle("Don't see provider", for: .normal) 
     case .showAllProviders: 
      button?.setTitle("Show all providers", for: .normal) 
     } 
     }) 
     .disposed(by: bag) 

    viewModel.items 
     .bind(to: collectionView 
     .rx 
     .items(cellIdentifier: "ProviderCell", cellType: ProviderCollectionViewCell.self)) { [ unowned self ] _, item, cell in 
      item.logoImage.bind(to: cell.imageView.rx.image).addDisposableTo(self.bag) 
     } 
     .addDisposableTo(bag) 

    collectionView 
     .rx 
     .modelSelected(TopProvidersPickerItem.self) 
     .bind(to: self.viewModel.selectedItem) 
     .addDisposableTo(bag) 

    viewAllProvidersButton 
     .rx 
     .tap 
     .bind(to: self.viewModel.showAllProvidersTrigger) 
     .addDisposableTo(bag) 
} 

} 

ich einen Test für den "keinen" Fall schrieb, habe aber nicht in der Lage gewesen, um herauszufinden, die anderen beiden Fälle:

import FBSnapshotTestCase 
import OHHTTPStubs 
import RxSwift 
@testable import AuthSuite 

class TopProvidersPickerViewControllerTests: FBSnapshotTestCase, 
ProvidersViewControllerTests { 

override func setUp() { 
    super.setUp() 
    recordMode = true 
} 

func testDoesNotShowButtonWhenLoadingProviders() { 
    let viewModel = TopProvidersPickerViewModel(items: .never()) 
    let controller = TopProvidersPickerViewController.instantiateViewController(with: viewModel) 
    presentViewController(controller) 

    FBSnapshotVerifyView(controller.view) 
} 

Antwort

0

Ich habe noch nie FB Snapshot Tester verwendet. Ich werde mich darum kümmern müssen.

Hier ist, wie ich es tun würde:

Ich würde die Enum auf die Viewcontroller aussetzen. setupRx() enthalten würde dies statt:

private func setupRx() { 

    viewModel.buttonTitle 
     .bind(to: viewAllProvidersButton.rx.title(for: .normal)) 
     .disposed(by: bag) 

    viewModel.buttonHidden 
     .bind(to: viewAllProvidersButton.rx.isHidden) 
     .disposed(by: bag) 

    // everything else  
} 

dann den Titel der Schaltfläche zu testen, zum Beispiel, würde ich diese Tests verwenden:

import XCTest 
import RxSwift 
@testable import RxPlayground 

class TopProvidersPickerViewModelTests: XCTestCase { 

    func testButtonTitleEmptyItems() { 
     let topProviders = Observable<[MVPD]>.just([]) 
     let decodableProviding = MockDecodableProviding() 

     let viewModel = TopProvidersPickerViewModel(topProviders: topProviders, imageLoader: decodableProviding) 

     var title: String = "" 
     _ = viewModel.buttonTitle.subscribe(onNext: { title = $0 }) 

     XCTAssertEqual(title, "Don't see provider") 
    } 

    func testButtonTitle12Items() { 
     let topProviders = Observable<[MVPD]>.just(Array(repeating: MVPD(), count: 12)) 
     let decodableProviding = MockDecodableProviding() 

     let viewModel = TopProvidersPickerViewModel(topProviders: topProviders, imageLoader: decodableProviding) 

     var title: String = "" 
     _ = viewModel.buttonTitle.subscribe(onNext: { title = $0 }) 

     XCTAssertEqual(title, "Don't see provider") 
    } 

    func testButtonTitle13Items() { 
     let topProviders = Observable<[MVPD]>.just(Array(repeating: MVPD(), count: 13)) 
     let decodableProviding = MockDecodableProviding() 

     let viewModel = TopProvidersPickerViewModel(topProviders: topProviders, imageLoader: decodableProviding) 

     var title: String = "" 
     _ = viewModel.buttonTitle.subscribe(onNext: { title = $0 }) 

     XCTAssertEqual(title, "Show all providers") 
    } 
} 


class MockDecodableProviding: DecodableProviding { 
    // nothing needed for these tests. 
} 
+0

Vielen Dank für die Hilfe, wirklich zu schätzen !! Ich kann das setupRx() atm nicht ändern: Wie würden wir die Tests so machen, wie es ist? – VeeArr

+0

Ich muss auch FBSnapshotTestCase anstelle von XCTest verwenden): – VeeArr

+0

Der ganze Punkt des Schreibens von Tests ist, so dass Sie * den zu testenden Code * ändern können. Das heißt, ich kann Ihnen bezüglich FBSnapshotTestCase nicht helfen. Ich habe gerade erst von deiner Frage gehört. –

Verwandte Themen