1

I am using ModelView-ViewModel in the project I am currently working and using RxSwift, RxBlocking & RxTests. Currently I am attempting to test the ViewModel but having many troubles to get my head around this.

So lets say I have an ExampleViewModel for my ExampleViewController. My ExampleViewModel is expecting an Observable stream which is the combination (combineLatest) of two streams from UITextField, one being if the textField is either focused and the other is the stream of text; so something like Observable<(Bool, String)>. Depending on whether focused and the context of the string my ExampleViewModel will emit an event into its internally exposed property which is an Observable the state of the UITextField's backgroundColor; Observable<UIColor>.

ExampleViewModel.swift :

class ExampleViewModel {

private let disposeBag = DisposeBag()

private let _textFieldColor: PublishSubject<UIColor>
var textFieldColor: Observable<UIColor> { get { return self._textFieldColor.asObservable() } }

init(textFieldObservable: Observable<(Bool, String)>) {
    textFieldObservable.subscribeNext { (focus, text) in
        self.validateTextField(focus, text: text)
    }.addDisposableTo(self.disposeBag)
}

func validateTextField(focus: Bool, text: String) {
    if !focus && !text.isEmpty {
        self._textFieldColor.onNext(UIColor.whiteColor())
    } else {
        self._textFieldColor.onNext(UIColor.redColor())
    }
}
}

(sorry I don't know how to format it correctly)

Basically I would like to test the ExampleViewModel class and test that it emits the correct UIColor by controlling the focus and text inputs.

Thanks

a.ajwani
  • 868
  • 1
  • 8
  • 21

1 Answers1

0

Thanks to the suggestion of my colleague I found a better way on structuring the ExampleViewModel for testability. By separating out the validation method with ExampleViewModel and setting the textFieldColor Observable by using the map operator in which the validator is used the validation is done outside and does not use Rx simplifying the testing of the logic.

ExampleViewModel

class ExampleViewModel {

var textFieldColor: Observable<UIColor>

init(
    textFieldText: Observable<String>,
    textFieldFocus: Observable<Bool>,
    validator: TextFieldValidator
) {
    self. textFieldColor = Observable.combineLatest(textFieldText, textFieldFocus) { ($0, $1) }. map { validator.validate($1, text: $0) }
}
}



 class TextFieldValidator {

func validate(focus: Bool, text: String) -> UIColor {
    if !focus && !text.isEmpty {
        return UIColor.whiteColor()
    } else {
        return UIColor.redColor()
    }
}
}
a.ajwani
  • 868
  • 1
  • 8
  • 21