I've a struct that returns lists of various kinds depending on received arguments. Those lists are lengthy and take time to create. I would like to write unit tests checking whether generated lists are of required characterictis (length, content, etc.)
I would like to instantiate different versions of that struct once per all tests using:
override class function setUp
When I try I get the error:
instance member 'shortWords' cannot be used on type 'TestSampleWords'
SampleWords.swift
import Foundation
struct SampleWords {
var wordSize: String
private var length: Int {
switch wordSize {
case "short":
5
case "long":
10
default:
7
}
}
private func randomString(length: Int) -> String {
// Source: https://stackoverflow.com/a/26845710/1655567
let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
return String((0..<length).map{ _ in letters.randomElement()! })
}
var wordsSet: [String] {
(0..<1001).map { _ in randomString(length: length) }
}
}
TestSampleWords.swift
import XCTest
@testable import SampleWords
final class TestsSampleWords: XCTestCase {
private var longWords: SampleWords!
private var shortWords: SampleWords!
// I'm adding 'class' modifier as I want for the setUp to run only once
override class func setUp() {
// At this junction I want to create a set of objects
// reflecting struct parameters and re-use them across tests
longWords = SampleWords(wordSize: "long")
shortWords = SampleWords(wordSize: "short")
}
override class func tearDown() throws {
longWords = nil
shortWords = nil
}
func testAreLists() {
XCTAssertTrue(longWords.wordsSet is [String])
XCTAssertTrue(shortWords.wordsSet is [String])
// Further tests continue in this and other methods
}
}
override class function setUp
is replaced with override function setUp
; however, this is not desired behaviour. I want to create a set of objects and re-use those in different tests.You cannot reference instance variables (private var longWords
, private var shortWords
) from a static/class context inside the class func
.
The solution is as simple as they come - just make those variables also static/class
:
private class var longWords: SampleWords!
private class var shortWords: SampleWords!
Then you will be able to assign to them in the class func setUp
.
A small downside will be that when used in test functions, which are not static, you will have to refer to them either as TestsSampleWords.longWords
or Self.longWords
(note the capital S
in Self
here).