skip to Main Content

I’m trying to put a very simple unitTest-Like function together for teaching Swift, when we’re not quite ready for the full XCTest framework.

I’ve put together this code:

enum TestFailure : Error {
    case testEqFailure(_ msg: String)
}

func testEq<E:Equatable>(_ actual: E, _ expected: E ) throws {
    if actual == expected { return }
    print("Test failed")
    print("Actual Result  : (actual)")
    print("Expected Result: (expected)")
    throw TestFailure.testEqFailure("Test Values were not equal")
}

try testEq(1,1)
try testEq(7,8)

It "works" just fine (as shown by the output):

Test failed
Actual Result  : 7
Expected Result: 8
Swift/ErrorType.swift:200: Fatal error: Error raised at top level: vPlay.TestFailure.testEqFailure("Test Values were not equal")
2021-11-01 10:36:52.050106-0400 vPlay[49261:2400984] Swift/ErrorType.swift:200: Fatal error: Error raised at top level: vPlay.TestFailure.testEqFailure("Test Values were not equal")

but when I run it, Xcode is highlighting the wrong source line:

Xcode highlighting incorrect exception source line

What am I missing? (BTW, this is being used in the top level code of a command line program to keep things simple and focus on the actual coding)

2

Answers


  1. Try calling the function with a do catch instead

    try testEq(1,1)
    
    do {
        try testEq(7,8)
    } catch {
        print(error)
    }
    

    The error I get in playground is "An error was thrown and was not caught:" but not pointing to the first function call rather the second function call.

    When you have a block of code that contains a method which can potentially throw an error you need to call the function with a do catch statement.
    When the throwing method fails and raises the error the execution will go into the catch block and be handled according to what you dictate within the catch block.

    The first function call is not failing because it doesn’t throw an error but if it is for whatever IDE your using then try a do catch on that call as well.

    Login or Signup to reply.
  2. If you want to teach a sudo assert test with a throwing function then you will have to teach error handling also or swift will fail when it has to handle the error being thrown.
    You could eliminate the throwing and enum error if you want to simplify this for a beginner but still get the point across.

    func testEq<E:Equatable>(_ actual: E, _ expected: E )  {
        if actual == expected { return }
        print("Test failed")
        print("Actual Result  : (actual)")
        print("Expected Result: (expected)")
        
    }
    
    testEq(1,1)
    testEq(7,8)
    

    This will print what you want to see, actual and expected with the print test failed along side it to simulate a failure.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search