2014-10-10 4 views
1

Я пытаюсь научиться испытывать с быстрыми и ловкими, и я написал простой одноплодной и некоторые тестыSwift одноточечно тесты

Singleton:

public class LocationManager : NSObject { 
// Singleton 
public class var sharedInstance : LocationManager { 
    struct Static { 
     static var instance : LocationManager? 
     static var token : dispatch_once_t = 0 
     } 
    dispatch_once(&Static.token) { 
     Static.instance = LocationManager() 
    } 
    return Static.instance! 
    } 
} 

Мои тесты:

class LocationManagerSpec: QuickSpec { 
override func spec() { 
    describe("Location manager") { 

     let locationManager = LocationManager.sharedInstance 

     context("initialized") { 
      it("is not nil") { 
       expect(locationManager).notTo(beNil()) 
      } 
      it("is unique") { 
       let tempLocationManager = LocationManager() 
       expect(locationManager).notTo(equal(tempLocationManager)) 
      } 
      it("and shared instances are same") { 
       let tempLocationManager = LocationManager.sharedInstance 
       expect(locationManager).to(equal(tempLocationManager)) 
      } 
     } 
    } 
} 
} 

Как я могу тест мой синглтон является потокобезопасным?

ответ

0

Чтобы проверить, что ваш Singleton является защищенным потоком, я сделал небольшой образец. Вы можете найти код в этом Github repo в основном:

  1. создающего пучок нитей, просящих синглтон
  2. хранения каждый возвращенный объекта внутри массива
  3. проверки всех объектов, содержащихся в этом массиве являются одинаковыми

Я нашел несколько проблем (используя Xcode 6.2 ergo Swift 1.1), даже сбой компилятора. Итак, следуя this accepted SO answer Я изменил вашу реализацию Singleton, избегая классического использования GCD. Эти указатели и небезопасные изменяемые указатели вам нужно управлять, и я получаю аварии из-за этого

Так ваш класс Singleton теперь:

import Foundation 


public class LocationManager: NSObject { 

    public class var sharedInstance: LocationManager { 
     struct Static { 
      static let instance: LocationManager = LocationManager() 
     } 
     return Static.instance 
    } 

} 

И проверить это, нужно подождать, пока все темы нет законченный. Как тест бегун работает на MainThread вам нужно использовать ожидание

describe("Accesing Location manager from multiple concurrent threads") { 
      context("When created") { 
       it("should return always the same object for every of these 500 threads") { 
        var allSingletons = Array<LocationManager>() 

        for i in 1...10 { 
         println("Launching thread \(i)") 

         dispatch_async(self.globalBackgroundQueue) { 
          allSingletons.append(LocationManager.sharedInstance) 
         } 
        } 

        expect(self.allSingletonsEqual(inArray: allSingletons, singleton: LocationManager.sharedInstance)).toEventually(beTrue(), timeout: 10) 

       } 
      } 

     } 

Важной частью это одна:

expect(self.allSingletonsEqual(inArray: allSingletons, singleton: LocationManager.sharedInstance)).toEventually(beTrue(), timeout: 10) 

Здесь я просто вызов функции, чтобы убедиться, если каждый объект сохраняется такая же, как пройденный Singleton, и давая 10 секунд тайм-аут

весь класс Test:

import Quick 
import Nimble 
import QuickNimbleExample 




class LocationManagerSpec: QuickSpec { 
    var globalBackgroundQueue: dispatch_queue_t { 
     return dispatch_get_global_queue(Int(QOS_CLASS_BACKGROUND.value), 0) 
    } 

    func allSingletonsEqual(#inArray: Array<LocationManager>, singleton: LocationManager) -> Bool { 

     for loc in inArray { 
      if loc != singleton { 
       return false 
      } 
     } 

     return true 
    } 


    override func spec() { 

     describe("Accesing Location manager from multiple concurrent threads") { 
      context("When created") { 
       it("should return always the same object for every of these 500 threads") { 
        var allSingletons = Array<LocationManager>() 

        for i in 1...10 { 
         println("Launching thread \(i)") 

         dispatch_async(self.globalBackgroundQueue) { 
          allSingletons.append(LocationManager.sharedInstance) 
         } 
        } 

        expect(self.allSingletonsEqual(inArray: allSingletons, singleton: LocationManager.sharedInstance)).toEventually(beTrue(), timeout: 10) 

       } 
      } 

     } 


      } 
} 
Смежные вопросы