Mock CLBeacon Object in Swift

754 Views Asked by At

I have been searching online for a way to mock a CLBeacon object in order to test one of my classes. All I can find is related to COMockito which is only compatible with Objective-c.

All I need, is to be able to create a mock CLBeacon and set its major minor and UUID values. The problem is that these parameters are read only.

Any idea on what I could do to have a mock CLBeacon with parameters that I set?

2

There are 2 best solutions below

2
On BEST ANSWER

I'm not sure why I always forget about NSCoding, but you can doctor up CLBeacon objects using KVO syntax. I finally got unit testing working with CLBeacon like this:

    let mockUUID = NSUUID(UUIDString: uuidString)
    let testBeacon = CLBeacon()
    testBeacon.setValue(testMajor, forKey: "major")
    testBeacon.setValue(testMinor, forKey: "minor")
    testBeacon.setValue(mockUUID, forKey: "proximityUUID")
    testBeacon.setValue(CLProximity.Far.rawValue, forKey: "proximity")
1
On

Probably late to the party. Posting it just in case anyone is facing up with the same problem.

Unfortunately, at least in iOS13 as the time of writing, all CLBeacon properties are shielded within an _internal NSObject property that, in turns, holds the relative value.

The result is that you cannot use simple value/key approach. Also the exposed public header for CLBeacon class doesn't expose the relative method to init with arbitrary value the internal object.

This gist, create a FakeBeacon Obj-C class, that re-enable the required init method, allowing such call also from Swift, in the following way:

var beacon = FakeBeacon(fakeWithUUID: UUID(uuidString: uuid)!,
    major: 1,
    minor: 100,
    proximity: 2,
    accuracy: 1,
    rssi: 0,
    timestamp: Date().timeIntervalSinceReferenceDate)

obviously, you shouldn't include such code in a production IPA, otherwise Apple's reject is inevitable.