LoginSignup
37
31

More than 5 years have passed since last update.

Swift2.0で追加された@testableはprivateにはアクセスできない

Last updated at Posted at 2015-06-25

Swift2.0でUnit Testを書く際に@testableというattributeが追加されました。
この@testableを使用する際の注意事項です。

まずはアクセス制御について確認しましょう。以前書いたものから引っ張ってきました。

アクセス制御

Swiftは モジュールソースファイル をアクセス制御の単位としています。

アクセスレベル 用途
public どこからでもアクセス可能 どこからでもアクセス可能なのでframeworkのAPIを定義する場合はこれを使う
internal デフォルトのアクセスレベル 自身のモジュールと同じモジュールのソースファイル内であればアクセス可能。何も指定しない場合はこれが指定される。
private 最も厳しいアクセスレベル モジュール内の同じソースファイルでなければアクセスできない。外部に隠蔽しておきたいものはこれを指定。

@testableの書き方

@testableimportと一緒に記載します。以下はProductKitというEmbedded Frameworkを作成し、そのUTを記述した際のものです。

ProductKitTests.swift
import XCTest
@testable import ProductKit

class ProductKitTests: XCTestCase {

    override func setUp() {
        super.setUp()
    }

    override func tearDown() {
        super.tearDown()
    }

    func testExample() {
        let something = Something(publicName: "public", internalName: "internal")
        something.publicHello(something.publicName)
        something.internalHello(something.internalName)
    }
}

2行目のimportの前に@testableを記述しています。internalなメソッドやプロパティに対してはこれでアクセス可能になります。

注意点

注意点としては、@testableをつけてもアクセス可能なのはinternalまでで、privateな関数、メソッド、プロパティにはアクセスできません。

よく考えれば、外部モジュールにさえしておけばinternalで十分隠蔽されている状態になります。モジュールが分かれていればinternalなプロパティやメソッドにはアクセスできないので。

いままで外部モジュールで作成したクラス内の、内部でしか使用しないメソッドなどはprivateにしていましたが、モジュールが分かれていれば参照不可能になるのでinternalで十分なのかもしれません。というか、そうしないとテスト不可能になります。

ただし同一モジュール内ではinternalなプロパティやメソッドにはアクセスできてしまうわけで、隠蔽したいからとprivateをつけてしまうと、外部モジュールであるテストターゲット内で参照不可能になってしまいます。

なんだか手が届かないところがかゆい感じです。

37
31
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
37
31