2014-09-26 11 views
7

Wie man einen Test schreiben, die einen Methodenaufruf mit schnellen und XCTest erwartet?XCTest erwarten Methodenaufruf mit schnellen

Ich kann OCMock verwenden, aber sie unterstützen nicht offiziell schnell, so dass nicht viel von einer Option.

+0

möglich Duplikat [Mocking in Swift] (http://stackoverflow.com/ Fragen/24174130/Mocking-in-Swift) – ColinE

+1

Der Unterschied von meiner Frage zu diesem ist, dass ich einen Methodenaufruf erwarten und nicht nur eine Methode verspotten. –

Antwort

4

Wie gesagt, Sie OCMock nicht Swift unterstützt (noch OCMockito), so jetzt der einzige Weg, ich sehe eine Hand gerollt Mock zu schaffen. In swift ist dies ein bisschen weniger schmerzhaft, da Sie innere Klassen innerhalb einer Methode erstellen können, aber immer noch nicht so praktisch wie ein spöttisches Framework.

Hier haben Sie ein Beispiel. Der Code ist selbsterklärend, das einzige, was ich tun musste (siehe EDIT 1 unten), um es zum Laufen zu bringen, besteht darin, die Klassen und Methoden, die ich verwenden möchte, als öffentlich zu deklarieren (scheint, dass die Testklassen nicht zu den Code-Modul der gleichen Anwendung - wird versuchen, eine Lösung dafür zu finden.

EDIT 1 2016/4/27: Das Deklarieren der Klassen, die Sie als öffentlich testen möchten, ist nicht mehr erforderlich, da Sie die Funktion "@testable import ModuleName" verwenden können.

Der Test:

import XCTest 
import SwiftMockingPoC 

class MyClassTests: XCTestCase { 

    func test__myMethod() { 
     // prepare 
     class MyServiceMock : MyService { 

      var doSomethingWasCalled = false 

      override func doSomething(){ 
       doSomethingWasCalled = true 
      } 

     } 
     let myServiceMock = MyServiceMock() 

     let sut = MyClass(myService: myServiceMock) 

     // test 
     sut.myMethod() 

     // verify 
     XCTAssertTrue(myServiceMock.doSomethingWasCalled) 
    } 

} 

MyClass.swift

public class MyClass { 

    let myService: MyService 

    public init(myService: MyService) { 
     self.myService = myService 
    } 

    public func myMethod() { 
     myService.doSomething() 
    } 

} 

MyService.swift

public class MyService { 

    public init() { 

    } 

    public func doSomething() { 

    } 

} 
+0

Ich würde nicht nur für „doSomethingWasCalled“ in der Mock-Klasse wie eine Variable zu erstellen und dann für jede Methode eine Assertion habe ich erwarte genannt zu werden. Ich wollte eher eine Variable außerhalb der Mock-Klasse mit expectationWithDescription deklarieren, ihre Erwartung in der Mock-Class-Methode erfüllen und dann waitForExpectationsWithTimeout im Test aufrufen. Aber das funktioniert nicht, der Test kompiliert nicht (oder gibt mir den "SourceKitService Crashed" -Fehler, erinnere mich nicht wirklich und kann jetzt nicht testen, weil mein Code nicht kompiliert, weil ich etwas anderes bin Umsetzung). –

+0

Auch ich kann eine Methode innerhalb des Tests nicht wie Sie überschreiben. Gleicher Fehler, "SourceKitService Crashed". –

+0

AFAIK XCTestExpectation ist für asynchrone Tests gedacht, ich sehe keinen Grund, es zu verwenden, es sei denn, Sie möchten es. Wenn Sie diese Methode überschreiben möchten, vergewissern Sie sich, dass Sie die Methoden und Klassen, die Sie in Ihrem Test verwenden möchten, öffentlich deklarieren. Der Code meiner Antwort funktioniert in Xcode für mich. – e1985