Xcode8.3からXCTestExpectationが拡張されたよ

# XCTestExpectation
XCTestで非同期テストを実施するときに利用するAPI

Xcode8.3からAPIが追加されました
[XCTextExpectation](https://developer.apple.com/reference/xctest/xctestexpectation?changes=latest_minor)
[XCTestCase](https://developer.apple.com/reference/xctest/xctestcase?changes=latest_minor)

## 従来の非同期テストの書き方

```
// setUp()などは省略

- (void)testExample {
    XCTestExpectation* expectation = [self expectationWithDescription:@"Hoge Test"];
    
    Hoge* hoge = [Hoge new];
    [hoge asyncMethod:^(NSError* error) {
        XCTAssertNil(error);

        // 終わったらfulfill
        [expectation fulfill];
    }];

    // 3秒間待つ
    [self waitForExpectationsWithTimeout:3.0 handler:nil];
}

```

## 新しい非同期テストの書き方
今までは`XCTestCase`クラスを経由して`XCTestExpectation`オブジェクトを作成する必要がありましたが、`XCTestExpectation`の指定イニシャライザを直接呼び出してのオブジェクト生成が可能になりました。
`XCTWaiter`クラスと組み合わせることによってできることが増えたようです。
`XCTestCase`に`waitForExpectations:timeout:`関数が追加されているので、これを使います。

```
- (void)testExample {
    // 指定イニシャライザ
    XCTestExpectation* expectation = [[XCTestExpectation alloc]initWithDescription:@"Hoge Test"];
    
    Hoge* hoge = [Hoge new];
    [hoge asyncMethod:^(NSError* error) {
        XCTAssertNil(error);

        [expectation fulfill];
    }];

    [self waitForExpectations:@[expectation] timeout:3.0];
}

```

## 追加されたプロパティ
いくつかプロパティが追加されました。

### expectationDescription
Descriptionを書き換えられるようになりました。

```
- (void)testExample {
    XCTestExpectation* expectation = [[XCTestExpectation alloc]initWithDescription:@"Hoge Test"];
    expectation.expectationDescription = @"Fuga Test";

    ・
    ・
    ・
}

```

### expectedFulFillmentCount
成功に必要なfulfill()の回数を指定可能になりました。
デフォルトは1回。

```
- (void)testExample {
    XCTestExpectation* expectation = [[XCTestExpectation alloc]initWithDescription:@"Hoge Test"];
    // expectedFulfillmentCountを2回に設定
    expectation.expectedFulfillmentCount = 2;

    Hoge* hoge = [Hoge new];
    [hoge asyncMethod:^(NSError* error) {
        XCTAssertNil(error);

        // 1回目
        [expectation fulfill];
    }];

    [hoge asyncMethod:^(NSError* error) {
        XCTAssertNil(error);

        // 2回以上呼ばれたら成功
        [expectation fulfill];
    }];

    [self waitForExpectations:@[expectation] timeout:3.0];
}

```

### assertForOverFulfill
expectedFulFillmentCountの回数以上のfulfill()が呼ばれた場合にエラーにするかどうか。
デフォルトはNO。(指定した回数以上fulfill()が呼ばれても成功扱い)
従来のAPIを使った場合も内部的にNOになる。

```
- (void)testExample {
    XCTestExpectation* expectation = [[XCTestExpectation alloc]initWithDescription:@"Hoge Test"];
    // 3回以上fulfill()が呼ばれたらエラーにする
    expectation.expectedFulfillmentCount = 2;
    expectation.assertForOverFulfill  = YES;

    Hoge* hoge = [Hoge new];
    [hoge asyncMethod:^(NSError* error) {
        XCTAssertNil(error);

        // 1回目
        [expectation fulfill];
    }];

    [hoge asyncMethod:^(NSError* error) {
        XCTAssertNil(error);

        // 2回目
        [expectation fulfill];
    }];

    [hoge asyncMethod:^(NSError* error) {
        XCTAssertNil(error);

        // 3回目の呼び出しでExceptionが発生
        // (NSException*) name: @"NSInternalInconsistencyException" - reason: @"API violation - multiple calls made to -[XCTestExpectation fulfill] for Hoge Test."
        [expectation fulfill];
    }];

    [self waitForExpectations:@[expectation] timeout:3.0];
}

```

### isInverted
テスト条件を反転？する。
条件を満たさない(指定した回数のfulfill()が呼ばれない)場合に成功となります。

```
- (void)testExample {
    XCTestExpectation* expectation = [[XCTestExpectation alloc]initWithDescription:@"Hoge Test"];
    // 2回fulfill()が呼ばれなければ成功
    expectation.expectedFulfillmentCount = 2;
    expectation.inverted = YES;

    Hoge* hoge = [Hoge new];
    [hoge asyncMethod:^(NSError* error) {
        XCTAssertNil(error);

        // 1回目
        [expectation fulfill];
    }];

    [hoge asyncMethod:^(NSError* error) {
        XCTAssertNil(error);

        // コメントアウトを外して2回目が呼ばれると失敗
        // Fulfilled inverted expectation "Hoge Test".
        // [expectation fulfill];
    }];

    [self waitForExpectations:@[expectation] timeout:3.0];
}

```