2016-11-29 27 views
6

Uygulamamda bildirimlerin doğru biçimde eklendiğini belirtmek isterim. Normalde bağımlılık enjeksiyonu ile bunu yapardım, ancak yeni UNUserNotificationCenter API'sini test etmenin bir yolunu düşünemiyorum.Birimi test ediyor iOS 10 bildirimleri

import Foundation 
import UserNotifications 

class NotificationCenterMock: UNUserNotificationCenter { 
    var request: UNNotificationRequest? = nil 
    override func add(_ request: UNNotificationRequest, withCompletionHandler completionHandler: ((Error?) -> Void)? = nil) { 
     self.request = request 
    } 
} 

Ancak UNUserNotificationCenter hiçbir erişilebilir başlatıcıları vardır ben alay başlatamazsınız:

ben bildirim isteğini yakalayacağı sahte nesne oluşturmak başladı.

Testler Simulator üzerinde testlerin durmasına izin vermesi istendiği için bildirim isteğini ekleyerek ve mevcut bildirimleri getirerek test edebileceğime bile emin değilim. Şu anda bildirim mantığını bir sarıcıya dönüştürdüm, bu yüzden en azından uygulama boyunca bunu elden geçirip el ile test edebiliyorum.

El ile yapılan sınamalardan daha iyi seçenek var mı?

cevap

7

Kullandığınız yöntemler için bir protokol oluşturabilir ve buna uymak için UNUserNotificationCenter üzerinde bir uzantı oluşturabilirsiniz. Bu protokol, yöntem uygulamalarını değiştirmek için orijinal UNUserNotificationCenter uygulaması ile sahte nesneniz arasında bir köprü görevi görür. İşte

Bir oyun alanında yazdığı bir örnek kod, ve gayet iyi çalışıyor:

/* UNUserNotificationCenterProtocol.swift */ 

// This protocol allows you to use UNUserNotificationCenter, and replace the implementation of its 
// methods in you test classes. 
protocol UNUserNotificationCenterProtocol: class { 
    // Declare only the methods that you'll be using. 
    func add(_ request: UNNotificationRequest, 
      withCompletionHandler completionHandler: ((Error?) -> Void)?) 
} 

// The mock class that you'll be using for your test classes. Replace the method contents with your mock 
// objects. 
class MockNotificationCenter: UNUserNotificationCenterProtocol { 
    func add(_ request: UNNotificationRequest, 
      withCompletionHandler completionHandler: ((Error?) -> Void)?) { 
    // Do anything you want here for your tests 
    print("Mock center log") 
    completionHandler?(nil) 
    } 
} 

// Must extend UNUserNotificationCenter to conform to this protocol in order to use it in your class. 
extension UNUserNotificationCenter: UNUserNotificationCenterProtocol { 
// I'm only adding this implementation to show a log message in this example. In order to use the original implementation, don't add it here. 
    func add(_ request: UNNotificationRequest, withCompletionHandler completionHandler: ((Error?) -> Void)?) { 
    print("Notification center log") 
    completionHandler?(nil) 
    } 
} 

/* ExampleClass.swift */ 

class ExampleClass { 

    // Even though the type is UNUserNotificationCenterProtocol, it will take UNUserNotificationCenter type 
    // because of the extension above. 
    var notificationCenter: UNUserNotificationCenterProtocol = UNUserNotificationCenter.current() 

    func doSomething() { 
    // Create a request. 
    let content = UNNotificationContent() 
    let request = UNNotificationRequest(identifier: "Request", 
              content: content, 
              trigger: nil) 
    notificationCenter.add(request) { (error: Error?) in 
     // completion handler code 
    } 
    } 
} 

let exampleClass = ExampleClass() 
exampleClass.doSomething() // This should log "Notification center log" 

/* TestClass.Swift (unit test class) */ 

class TestClass { 

    // Create your mock class. 
    var notificationCenter: UNUserNotificationCenterProtocol = MockNotificationCenter() 

    func doSomething() { 
    // Create a mock Request. 
    let fakeContent = UNNotificationContent() 
    let mockRquest = UNNotificationRequest(identifier: "mock", 
              content: fakeContent, 
              trigger: nil) 
    notificationCenter.add(mockRquest) { (error: Error?) in 
     // completion handler code 
    } 
    } 
} 

let testClass = TestClass() 
testClass.doSomething() // This should log "Mock center log" 

yeni yöntemi kullanmak her sefer, protokole eklemek gerekecek unutmayın, ya derleyici şikayette bulunur.

Bu yardımcı olur umarız!

+0

Akıllı bir çözüm gibi görünüyor, teşekkürler! – squarefrog

+0

Bu harika bir yanıttır. 'Func getNotificationSettings (completionHandler: @escaping (UNNotificationSettings) -> Swift.Void) 'a benzer bir yaklaşımı izlemenin mümkün olduğunu düşünüyor musunuz? Örneklendirilemediğinden döndürülen 'UNNotificationSettings' nesnesine alay etme konusunda sorun yaşıyorum. – JimmyB

İlgili konular