5

I am trying to test this class (Swiftris/Swifteris/Array2D.swift):

class Array2D<T> {

    let rows: Int
    let columns: Int

    var array: Array<T?>

    init(rows: Int, columns: Int) {
        self.rows = rows
        self.columns = columns

        array = Array<T?>(count:rows * columns, repeatedValue: nil)
    }

    subscript(column: Int, row: Int) -> T? {
        get {
            return array[(row * columns) + column]
        }
        set {
            array[(row * columns) + column] = newValue
        }
    }
}

With this simple test (Swiftris/SwiftrisTests/Array2DTest.swift):

import UIKit
import XCTest

class Array2DTest: XCTestCase {

    override func setUp() {
        super.setUp()
        // Put setup code here. This method is called before the invocation of each test method in the class.
    }

    func testHasRows() {
        var array: Array2D = Array2D(rows: 10, columns: 15)
        XCTAssertEqual(array.rows, 20, "an Array2D instance should have the correct number of rows")
    }
}

It unexplainably fails to resolve Array2D:

Swifteris/SwifterisTests/Array2DTest.swift:12:20: Use of undeclared type 'Array2D' 

Do I need to import my own module into my tests? This is pretty puzzling since I did the exact same thin in another project and had no trouble resolving classes under test.

max
  • 96,212
  • 14
  • 104
  • 165

1 Answers1

8

You have 2 options.

Add Array2D.swift to SwifterisTests Target Membership

It's very simple

screenshot

Import Swifteris to Array2DTest.swift

Basically this method is recommended, but it's relatively annoying.

At first, you have to declare all testable classes/methods/properties as public:

Array2D.swift:

public class Array2D<T> {

    public let rows: Int
    public let columns: Int

    private var array: Array<T?>

    public init(rows: Int, columns: Int) {
        self.rows = rows
        self.columns = columns

        array = Array<T?>(count:rows * columns, repeatedValue: nil)
    }

    public subscript(column: Int, row: Int) -> T? {
        get {
            return array[(row * columns) + column]
        }
        set {
            array[(row * columns) + column] = newValue
        }
    }
}

Then, import main module Swifteris to test module SwifterisTests

import XCTest
import Swifteris

// Here Array2D is avaiable.

More discussion on this Q/A: Swift, access modifiers and unit testing

Community
  • 1
  • 1
rintaro
  • 51,423
  • 14
  • 131
  • 139
  • Any idea why doing `Array2D(rows: 9, columns: 10)` gives me `Argument for generic parameter 'T' could not be inferred`? – max Nov 02 '14 at 11:25
  • 1
    Because you didn't provide any information about `T`. For example , `var array = Array2D(rows: 9, columns: 10)` would be OK, in that case `T` will be bound to `String`. – rintaro Nov 02 '14 at 11:47