2016-01-28 24 views
5

Sulla base di risposte a this question, mi sento felice con la semplicità e la facilità d'uso dei seguenti due metodi per la sincronizzazione:Come possono essere efficacemente testati questi metodi di sincronizzazione?

func synchronized(lock: AnyObject, closure:() -> Void) { 
    objc_sync_enter(lock) 
    closure() 
    objc_sync_exit(lock) 
} 

func synchronized<T>(lock: AnyObject, closure:() -> T) -> T { 
    objc_sync_enter(lock) 
    defer { objc_sync_exit(lock) } 
    return closure() 
} 

Ma per essere sicuri che stanno effettivamente facendo quello che voglio, voglio avvolgere questi in pile di test unitari. Come posso scrivere unit test che testano efficacemente questi metodi (e mostrano che stanno effettivamente sincronizzando il codice)?

Idealmente, mi piacerebbe anche che questi test unitari fossero il più semplici e chiari possibile. Presumibilmente, questo test dovrebbe essere un codice che, se eseguito all'esterno del blocco di sincronizzazione, fornirebbe un insieme di risultati, ma fornirà un insieme completamente separato di risultati all'interno di questi blocchi sincronizzati.

+0

Stai cercando di scrivere un test per verificare che il blocco sincronizzato sincronizza nel caso generale, o stai cercando di verificare che il codice che si basa sul blocco sincronizzato viene sincronizzato? –

+0

@ WillM.I sono interessato al caso generale. Voglio un test unitario che verifichi che stia sincronizzando qualsiasi codice eseguito attraverso di esso. – nhgrif

+0

Ok, ho buttato qualcosa insieme che dovrebbe dimostrarlo. –

risposta

1

Ecco un XCTest eseguibile che verifica la sincronizzazione. Se si sincronizza delayedAddToArray, funzionerà, altrimenti fallirà.

class DelayedArray:NSObject { 
    func synchronized(lock: AnyObject, closure:() -> Void) { 
     objc_sync_enter(lock) 
     closure() 
     objc_sync_exit(lock) 
    } 

    private var array = [String]() 
    func delayedAddToArray(expectation:XCTestExpectation) { 
     synchronized(self) { 
      let arrayCount = self.array.count 
      self.array.append("hi") 
      sleep(5) 
      XCTAssert(self.array.count == arrayCount + 1) 
      expectation.fulfill() 
     } 
    } 
} 

func testExample() { 
    let expectation = self.expectationWithDescription("desc") 
    let expectation2 = self.expectationWithDescription("desc2") 

    let delayedArray:DelayedArray = DelayedArray() 
    // This is an example of a functional test case. 
    let thread = NSThread(target: delayedArray, selector: "delayedAddToArray:", object: expectation) 
    let secondThread = NSThread(target: delayedArray, selector: "delayedAddToArray:", object: expectation2) 
    thread.start() 
    sleep(1) 
    secondThread.start() 

    self.waitForExpectationsWithTimeout(15, handler: nil) 
}