I am trying to use a public struct
public struct Person {
public let name: String
}
in a unit test (XCTest):
let person = Person(name: "Paul")
Test build fails with error:
'Person' cannot be constructed because it has no accessible initializers.
In order to build the test I need to write an initializer for the struct. Does not feel right because structs already have initializers. Does anyone have a better solution?
Xcode version 6.1.1 (6A2008a)
The problem is that the automatically synthesised initialiser you get with a struct is synthesised as internal
, meaning it can't be accessed from another module.
Your unit tests currently run in another module, so they can't see the initialiser. As Ben-G points out in his answer, this is addressed as of Swift 2.0 with the @testable
attribute.
It's part of the general brokenness of unit testing in Swift projects. The unit testing module should have special access to the app modules, otherwise you have to add loads of access control baggage.
From the documentation:
Default Memberwise Initializers for Structure Types
The default memberwise initializer for a structure type is considered private if any of the structure’s stored properties are private. Otherwise, the initializer has an access level of internal.
As with the default initializer above, if you want a public structure type to be initializable with a memberwise initializer when used in another module, you must provide a public memberwise initializer yourself as part of the type’s definition.
This is fixed in Swift 2.0 with the @testable
attribute.
If you import your module into the tests with @testable
the synthesized initializers will become visible to your tests.
You can find a brief intro to @testable
here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With