Search code examples
swiftunit-testingmockingstubspy

How to unit test a textView using a spy


I have a cell that contains a textView and i would like to test that the properties of that textView are set correctly using unit tests. However i seem to have hit a blocker when it comes to having access to the textView in the test since its private.

Is there a way I can test my textView:-

Here is my code

class MyCell {

  private let myText: UITextView = {
      let textView = UITextView()
      textView.isScrollEnabled = false
      textView.isEditable = false

      return textView
    }()

  func setup(viewModel: MYViewModel) {

      if viewModel.someValue {
          myText.backgroundColor = UIColor.red
      } else {
          myText.backgroundColor = .clear
      }

    }
}

Is it possible to test something like the testView's background color is set to clear ?


Solution

  • Unless you want to relax the access level of myText from private to internal (the default if you don't specify it), there is no direct way to test it.

    The only suggestion I have to test this indirectly would be to use snapshot testing.

    You could write two snapshot tests, one for each value of .someValue from your MYViewModel.

    Another option to make the testing –and maintainability– of your view straightforward is to introduce a ViewConfiguration value type, following the humble view pattern.

    Basically, you can have a struct in between MYViewModel and MyCell that describes each of the view properties for MyCell.

    struct MyCellViewConfiguration {
      let textFieldBackgroundColor: UIColor
    }
    
    extension MYViewModel {
    
      var viewConfiguration: MyCellViewConfiguration = {
        return MyCellViewConfiguration(
          textFieldBackgroundColor: someValue ? .red : .clear
        )
      }
    }
    
    extension MyCell {
    
      func setup(with configuration: MyCellViewConfiguration) {
        myText.backgroundColor = configuration.textFieldBackgroundColor
      }
    }
    

    The code in setup(with configuration: MyCellViewConfiguration) is so simple –just a 1-to-1 assignment– that you can get away without testing it.

    You can then write test for how MyCellViewConfiguration is computed from MYViewModel.