使用
Swift,在运行XCTest单元测试时会调用两次单例初始化程序.
但是,没有Objective-C的问题,init()方法只按预期调用一次.
以下是构建两个测试项目的方法:
Objective-C的
单身人士班
使用测试创建一个空的Objective-C项目.添加以下裸机单例:
#import "Singleton.h" @implementation Singleton + (Singleton *)sharedInstance { static Singleton *sharedInstance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken,^{ sharedInstance = [[Singleton alloc] init]; // Do any other initialisation stuff here }); return sharedInstance; } - (instancetype)init { self = [super init]; if (self) { NSLog(@"%@",self); } return self; } @end
AppDelegate中
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. [Singleton sharedInstance]; return YES; }
XCTestCase
- (void)testExample { [Singleton sharedInstance]; // This is an example of a functional test case. XCTAssert(YES,@"Pass"); }
结果
如果向单例的init方法添加断点并运行测试,断点将只按预期命中一次.
迅速
现在创建一个新的Swift项目并做同样的事情.
独生子
创建单例,将测试目标添加到其目标成员资格
class Singleton { class var sharedInstance : Singleton { struct Static { static var onceToken : dispatch_once_t = 0 static var instance : Singleton? = nil } dispatch_once(&Static.onceToken) { Static.instance = Singleton() } return Static.instance! } init() { NSLog("\(self)") } }
AppDelegate中
func application(application: UIApplication,didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { // Override point for customization after application launch. Singleton.sharedInstance return true }
XCTestCase
func testExample() { // This is an example of a functional test case. Singleton.sharedInstance XCTAssert(true,"Pass") }
结果
这一次,如果你向单例的init方法添加断点并运行测试,断点将被击中两次,首先是来自app委托,然后来自测试用例,即你将有两个单例实例.
我错过了什么吗?
解决方法
由于应用程序模块和测试模块是分离的模块,因此当您将Singleton.swift文件添加到测试目标成员时,YourApp.Singleton和YourAppTest.Singleton不是同一个类.这就是为什么init叫了两次.
而不是那样,您应该在测试文件中导入主模块:
import YourAppName func testExample() { // This is an example of a functional test case. Singleton.sharedInstance XCTAssert(true,"Pass") }
并且您的Singleton类必须声明为public.见Swift,access modifiers and unit testing
public class Singleton { public class var sharedInstance : Singleton { struct Static { static var onceToken : dispatch_once_t = 0 static var instance : Singleton? = nil } dispatch_once(&Static.onceToken) { Static.instance = Singleton() } return Static.instance! } init() { NSLog("\(self)") } }
不要忘记从测试目标成员身份中删除Singleton.swift.