Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift Unit testing with XCTAssertThrows analogue

Tags:

swift

Is there any equivalent to check for throwing exceptions in swift language Unit tests?

For example I Have a class:

class Square : NSObject{

    let sideLength: Int

    init(sideLength: Int) {
        assert(sideLength >= 0, "Wrong initialization of Square class with below zero side length")
        self.sideLength = sideLength
        super.init()
    }
}

and Test to check it work. In objective C I can write test method like this:

- (void)testInitializationWithWrongSideLengthThrowsExceptions{
   XCTAssertThrows([[Shape alloc] initWithSideLength: -50], "Should throw exceptions on wrong side values initialisations");
}

What is Swift equal technic?

like image 627
Nikolay Shubenkov Avatar asked Jun 05 '14 06:06

Nikolay Shubenkov


People also ask

How does swift implement unit testing?

To create new unit case in iOS, go to File -> New -> File, and then select Unit Test Case Class. Doing so creates a template just like the one you got with your project. In our case, we want to name the file to correspond with the new Pokemon-related data structures we have introduced.

Can unit tests use databases?

Properties of unit database testingUnit tests can be automated, and you can script a set of database operations with the same ease as executing code; Unit tests are great for testing individual triggers, views, and sprocs.

Can unit testing be manual?

Unit testing can be done manually but is usually automated. Unit testing is a part of the test-driven development (TDD) methodology that requires developers to first write failing unit tests. Then they write code in order to change the application until the test passes.

What is unit testing with real time example?

An example of a real-world scenario that could be covered by a unit test is a checking that your car door can be unlocked, where you test that the door is unlocked using your car key, but it is not unlocked using your house key, garage door remote, or your neighbour's (who happen to have the same car as you) key.


2 Answers

If you add the following three files to your tests:

//  ThrowsToBool.h
#import <Foundation/Foundation.h>

/// A 'pure' closure; has no arguments, returns nothing.
typedef void (^VoidBlock)(void);

/// Returns: true if the block throws an `NSException`, otherwise false
BOOL throwsToBool(VoidBlock block);


//  ThrowsToBool.m
#import "ThrowsToBool.h"

BOOL throwsToBool(VoidBlock const block) {
    @try {
        block();
    }
    @catch (NSException * const notUsed) {
        return YES;
    }
    return NO;
}


// xxxTests-Bridging-Header.h
#import "ThrowsToBool.h"

Then you can write:

XCTAssert(throwsToBool {
   // test code that throws an NSException
})

But it doesn't work for assert or precondition :(

PS I got the idea from: http://modocache.io/xctest-the-good-parts

like image 132
Howard Lovatt Avatar answered Sep 20 '22 12:09

Howard Lovatt


I think the assert()-function should only be used for debug-purposes. Not only because of the following statement from Apple's Swift-Book (https://itun.es/de/jEUH0.l):

„Assertions cause your app to terminate and are not a substitute for designing your code in such a way that invalid conditions are unlikely to arise.“

Thats why I would solve this as follows:

import Cocoa
import XCTest

class Square
{
    let sideLength: Int

    init(_ sideLength: Int)
    {
        self.sideLength = sideLength >= 0 ? sideLength : 0
    }
}

class SquareTests: XCTestCase
{
    override func setUp() { super.setUp() }
    override func tearDown() { super.tearDown() }

    func testMySquareSideLength() {
        let square1 = Square(1);
        XCTAssert(square1.sideLength == 1, "Sidelength should be 1")

        let square2 = Square(-1);
        XCTAssert(square2.sideLength >= 0, "Sidelength should be not negative")
    }
}

let tester = SquareTests()
tester.testMySquareSideLength()
like image 32
zoma Avatar answered Sep 18 '22 12:09

zoma