Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to expect an Objective-C property with Cuckoo and OCMock? #399

Open
chrisjf opened this issue Sep 21, 2021 · 5 comments
Open

How to expect an Objective-C property with Cuckoo and OCMock? #399

chrisjf opened this issue Sep 21, 2021 · 5 comments
Labels
help wanted This issue is asking for a way to solve a problem.

Comments

@chrisjf
Copy link

chrisjf commented Sep 21, 2021

Hello, I'm new to Cuckoo and have a basic question. How can I properly expect that a property is called in an Objective-C class? Please find below the relevant files. Thanks for your help in advance!

//  Controller.swift

import Foundation

class Controller {

    let manager: Manager

    init(manager: Manager = Manager()) {
        self.manager = manager
    }

    func doSomething() {
        manager.shouldDisableAdIdentitySharing = true
    }

}
//  Manager.h

 #import <Foundation/Foundation.h> 

NS_ASSUME_NONNULL_BEGIN

@interface Manager: NSObject

@property (nonatomic, getter=shouldDisableAdIdentitySharing) BOOL disableAdIdentitySharing;

@end

NS_ASSUME_NONNULL_END
//  Manager.m

#import "Manager.h"

@implementation Manager

@end
//  CuckooSampleTests.swift

@testable import CuckooSample
import Cuckoo
import OCMock
import XCTest

class CuckooSampleTests: XCTestCase {

    func testExample() throws {
        let mockManager = objcStub(for: Manager.self) { stubber, mock in
//            stubber.when(mock.shouldDisableAdIdentitySharing).thenDoNothing()
        }

        let controller = Controller(manager: mockManager)

        controller.doSomething()

        objcVerify(mockManager.shouldDisableAdIdentitySharing)
    }

}

Screen Shot 2021-09-21 at 18 11 58

If Manager was a Swift class, I could just write something like when(stub.shouldDisableAdIdentitySharing.set(any())).thenDoNothing() but how can I do this for an Objective-C class?

@chrisjf chrisjf changed the title How to stub an Objective-C property with Cuckoo and OCMock How to expect an Objective-C property with Cuckoo and OCMock? Sep 21, 2021
@MatyasKriz MatyasKriz added the help wanted This issue is asking for a way to solve a problem. label Dec 2, 2021
@MatyasKriz
Copy link
Collaborator

Does the mock have the method setDisableAdIdentitySharing? It's been a while since we've implemented the Obj-C support, so it's possible that property setters can't be mocked this way. In that case, this needs to be implemented on top of the current functionality and I'm sorry that Cuckoo doesn't support this yet. 😕

@chrisjf
Copy link
Author

chrisjf commented Jan 4, 2022

Hey Matyas! Thanks for the reply.

Does the mock have the method setDisableAdIdentitySharing?

setDisableAdIdentitySharing is auto-synthesized by the compiler from the property disableAdIdentitySharing.

It's been a while since we've implemented the Obj-C support, so it's possible that property setters can't be mocked this way. In that case, this needs to be implemented on top of the current functionality and I'm sorry that Cuckoo doesn't support this yet.

Alright, thanks for the information. I'll close the issue as I understand now that it's not possible to mock Obj-C properties with Cuckoo/OCMock in Swift.

@chrisjf chrisjf closed this as completed Jan 4, 2022
@MatyasKriz
Copy link
Collaborator

I'd prefer to keep it open to have something to think about when adding new features as this seems to be pretty useful to add.
I'm not available much at the moment, but it's still better to let others know about this and to not let it get forgotten in issue history.

@MatyasKriz MatyasKriz reopened this Jan 4, 2022
@ajpallares
Copy link
Contributor

I've also faced this issue and there's a simple walkaround to mock Obj-C setters with the current implementation of Cuckoo:

when({ stub.shouldDisableAdIdentitySharing = false }()).thenDoNothing()

The problem with primitive data types in Obj-C is that we can't use the OCMArg.any() matcher as for reference types. Therefore, we need to mock the setters with the exact value set.

@MatyasKriz
Copy link
Collaborator

@ajpallares, that's a great find! Thanks for sharing, I'll have to add this case to the tests and the README so that it's documented, but it seems acceptable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted This issue is asking for a way to solve a problem.
Projects
None yet
Development

No branches or pull requests

3 participants