1

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?

ShEsKo
  • 157
  • 1
  • 13

2 Answers2

2

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")
Vramin
  • 58
  • 6
  • Sorry for the late response, I just tried it out and it doesn't seem to successfully change the major, minor and UUID values. When I try to print the CLBeacon object it shows that all its values are set to null. I put the code you shared on the setUp() Function, am I doing something wrong? – ShEsKo Feb 01 '16 at 01:05
  • 6
    With Swift 3, I get a `NSUnknownKeyException`. Has anybody been able to work around this please? – James Webster Nov 24 '16 at 08:16
2

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.

valvoline
  • 7,737
  • 3
  • 47
  • 52
  • Hi there. This appears to be your gist. I would like to use this it but only if it has an open source license. Can you tell me what license this code is under? Thank you – ironclock Jan 24 '23 at 16:49