ios - Swift Singleton Init Called Twice in XCTest -
with swift, singleton initializer called twice when running xctest unit tests.
no problems objective-c, though, init() method called once, expected.
here's how build 2 test projects:
objective-c
singleton class
create empty objective-c project tests. add following bare-bones singleton:
#import "singleton.h" @implementation singleton + (singleton *)sharedinstance { static singleton *sharedinstance = nil; static dispatch_once_t oncetoken; dispatch_once(&oncetoken, ^{ sharedinstance = [[singleton alloc] init]; // other initialisation stuff here }); return sharedinstance; } - (instancetype)init { self = [super init]; if (self) { nslog(@"%@", self); } return self; } @end
appdelegate
in application delegate add call singleton this:
- (bool)application:(uiapplication *)application didfinishlaunchingwithoptions:(nsdictionary *)launchoptions { // override point customization after application launch. [singleton sharedinstance]; return yes; }
xctestcase
also add call singleton generated test class:
- (void)testexample { [singleton sharedinstance]; // example of functional test case. xctassert(yes, @"pass"); }
results
if add breakpoint singleton's init
method , run tests, breakpoint hit once, expected.
swift
now create new swift project , same thing.
singleton
create singleton, add test target target memberships
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 customization after application launch. singleton.sharedinstance return true }
xctestcase
func testexample() { // example of functional test case. singleton.sharedinstance xctassert(true, "pass") }
results
this time, if add breakpoint singleton's init
method , run tests, breakpoint hit twice, first app delegate, test case, i.e. you'll have 2 instances of singleton.
am missing anything?
since application module , tests module separated modules, when add singleton.swift
file test target member, yourapp.singleton
, yourapptest.singleton
not same class. that's why init
called twice.
instead of that, should import
main module in test file:
import yourappname func testexample() { // example of functional test case. singleton.sharedinstance xctassert(true, "pass") }
and singleton
class must declared public
. see swift, access modifiers , 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)") } }
don't forget remove singleton.swift
test target membership.
Comments
Post a Comment