LoginSignup
7
1

More than 5 years have passed since last update.

Cuckooでモックを使ったテストをする

Posted at

目的

  • テストの際に、都度Mockクラスを作るのが面倒なので楽したい

探してみるとCuckooというライブラリがあったので使ってみる。

導入

readmeにあるようにすすめれば大丈夫
https://github.com/Brightify/Cuckoo

Run Script

テストターゲットのBuild PhasesにRun Scriptを足すように言われるが、Compile Sourcesより先に実行されるようにしておくと良さそう(一瞬はまった)

テストのたびにファイルのコメントのタイムスタンプが更新されて鬱陶しいので、--no-timestamp オプションを追加しておく

# Define output file. Change "$PROJECT_DIR/${PROJECT_NAME}Tests" to your test's root source folder, if it's not the default name.
OUTPUT_FILE="$PROJECT_DIR/${PROJECT_NAME}Tests/GeneratedMocks.swift"
echo "Generated Mocks File = $OUTPUT_FILE"

# Define input directory. Change "${PROJECT_DIR}/${PROJECT_NAME}" to your project's root source folder, if it's not the default name.
INPUT_DIR="${PROJECT_DIR}/${PROJECT_NAME}"
echo "Mocks Input Directory = $INPUT_DIR"

# Generate mock files, include as many input files as you'd like to create mocks for.
"${PROJECT_DIR}/Carthage/Checkouts/Cuckoo/run" generate --no-timestamp --testable  "$PROJECT_NAME" \
--output "${OUTPUT_FILE}" \
"$INPUT_DIR/MyModel.swift" \
# ... and so forth, the last line should never end with a backslash

# After running once, locate `GeneratedMocks.swift` and drag it into your Xcode test target group.

MyModel.swift以降に、モック化したいファイルを追記。つまり、モック対象が増えるたびにここをアップデートする必要がある。。。

あんまりいい例が思いつかなかったんですが...
ViewModelのとあるメソッドがModelのメソッドを実行していること を確認したい場合の例

テスト対象

MyViewModel.swift
class MyViewModel {
    let model: MyModel

    init(_ model: MyModel) {
        self.model = model
    }

    func doSomethingWithModel() {
        model.someRequest()
    }
}

モック化したい

MyModel.swift
class MyModel {
    func someRequest() {
        // APIで云々...
    }
}

テストコード

MyViewModelTest.swift
class MyViewModelTest: XCTestCase {
    var mock: MockMyModel!

    override func setUp() {
        // 対象にしたいprotocol/classの頭にMockをつけたclassが用意されるので使う
        mock = MockMyModel()
        stub(mock) { (mock) in
            // メソッドがコールされても何もしないことを設定する
            when(mock.someRequest()).thenDoNothing()
        }
    }

    func testDoSomethingWithModel() {
        // mockを注入
        let viewModel = MyViewModel(mock)
        viewModel.doSomethingWithModel()
        // mockのメソッドが呼ばれていることを確認する
        verify(mock, times(1)).someRequest()
    }
}

流石に自分でモックを書くよりは早そうですね!

7
1
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
7
1