Abhilasha
Abhilasha

Reputation: 949

Unit test case view controller crash swift

I am writing unit test cases for the view controllers in my iOS app. I am trying to test if the UI elements involving IBOutlets are not nil as in the code below.

class ClientsViewControllerTests: XCTestCase {

var clientsVC: ClientsTableViewController?

override func setUp() {
    super.setUp()

    let storyboard = UIStoryboard(name: "Clients", bundle: nil)

    clientsVC = storyboard.instantiateInitialViewController() as? ClientsTableViewController

    if let vc = clientsVC?{
        vc.loadView()
    }
}

override func tearDown() {

    super.tearDown()
    clientsVC = nil
}

func testClientViewControllerNotNil(){

    XCTAssertNotNil(clientsVC, "view controller cannot be nil")
}

I test fails and outputs "view controller cannot be nil"

I fail to understand why.However, the below test passes:

func testStoryBoard(){
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    var vc = storyboard.instantiateViewControllerWithIdentifier("MainVC") as UIViewController
    XCTAssertNotNil(vc,"Storyboard is not connected with a viewcontroller")

But I need to do it in the 1st method as I want to test for the IBOutlet bindings for the Specific viewController like:

XCAssertNotNil(vc.sendButton, "Send button is nil")

Kindly guide me why the test is failing and also how to test outlet binding and the action binding in ViewControllers

Upvotes: 4

Views: 2880

Answers (2)

Abhilasha
Abhilasha

Reputation: 949

After lots of trial n error we figured out the following code works for us. The issue was we were passing 'nil' value in bundle parameter. When this was replaced with the following line it started to work. bundle: NSBundle(forClass: self.dynamicType))

The working code:

let storyboard = UIStoryboard(name: "Clients", bundle: NSBundle(forClass: self.dynamicType))

var vc = storyboard.instantiateViewControllerWithIdentifier("ClientsVCTable") as ClientsTableViewController

vc.loadView()

XCTAssertNotNil(vc.clientSearchBar,"Not Nil")

Also for the IBActions:

let storyboard = UIStoryboard(name: "Login", bundle: NSBundle(forClass: self.dynamicType))

var vc = storyboard.instantiateViewControllerWithIdentifier("LoginViewController") as LoginViewController

vc.loadView()

let actions : NSArray = vc.signInButton.actionsForTarget(vc, forControlEvent: UIControlEvents.TouchUpInside)!

XCTAssertTrue(actions.containsObject("login"), "IBActions not found")

Upvotes: 5

karthikPrabhu Alagu
karthikPrabhu Alagu

Reputation: 3401

Put a break point inside setUp method to check clientsVC object is initialized or not. try instantiateViewControllerWithIdentifier("Client") method to initialize.

Keep in mind that setUp and tearDown method will be called before and after the execution of each test method in the class respectively.

Upvotes: 0

Related Questions