11

いくつかの日付計算をテストする必要がありますが、そのためにNSDate()は Swift でモックする必要があります。アプリ全体が Swift で書かれているので、テストも書きたいと思います。

メソッドの入れ替えを試みましたが、うまくいきません (または、何か間違ったことをしている可能性が高いです)。

extension NSDate {
    func dateStub() -> NSDate {
        println("swizzzzzle")
        return NSDate(timeIntervalSince1970: 1429886412) // 24/04/2015 14:40:12
    }
}

テスト:

func testCase() {
    let original = class_getInstanceMethod(NSDate.self.dynamicType, "init")
    let swizzled = class_getInstanceMethod(NSDate.self.dynamicType, "dateStub")
    method_exchangeImplementations(original, swizzled)
    let date = NSDate()
// ...
}

ただしdate、常に現在の日付です。

4

3 に答える 3

9

免責事項 - 私は Swift のテストに慣れていないので、これはひどくハックな解決策かもしれませんが、私もこれに苦労しているので、これが誰かの助けになることを願っています.

この説明は大きな助けになることがわかりました。

NSDate とコードの間にバッファー クラスを作成する必要がありました。

class DateHandler {
   func currentDate() -> NSDate! {
      return NSDate()
   }
}

次に、NSDate() を使用するすべてのコードでバッファ クラスを使用し、デフォルトの DateHandler() をオプションの引数として提供します。

class UsesADate {
   func fiveSecsFromNow(dateHandler: DateHandler = DateHandler()) -> NSDate! {
      return dateHandler.currentDate().dateByAddingTimeInterval(5)
   }
}

次に、テストで元の DateHandler() から継承するモックを作成し、それをテスト対象のコードに「挿入」します。

class programModelTests: XCTestCase {

    override func setUp() {
        super.setUp()

        class MockDateHandler:DateHandler {
            var mockedDate:NSDate! =    // whatever date you want to mock

            override func currentDate() -> NSDate! {
                return mockedDate
            }
        }
    }

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

    func testAddFiveSeconds() {
        let mockDateHandler = MockDateHandler()
        let newUsesADate = UsesADate()
        let resultToTest = usesADate.fiveSecondsFromNow(dateHandler: mockDateHandler)
        XCTAssertEqual(resultToTest, etc...)
    }
}
于 2015-12-04T18:32:09.127 に答える
4

スウィズリングを使用するのではなく、テストをサポートするようにシステムを実際に設計する必要があります。多くのデータ処理を行う場合は、それを使用する関数に適切な日付を挿入する必要があります。このようにして、テストはこれらの関数に日付を挿入してテストし、他のさまざまな状況で (日付を使用するメソッドをスタブ化するときに) 正しい日付が挿入されることを確認する他のテストがあります。

具体的には、スウィズルの問題については、IIRCNSDateはクラス クラスターであるため、別のクラスが「サイレントに」作成されて返されるため、交換するメソッドが呼び出される可能性は低くなります。

于 2015-04-27T07:59:11.747 に答える