简体   繁体   中英

Mocking Objective-C code in Swift Unit-Tests

NOTE: This isn't my actual code, I re-typed it in a simple fashion on to here for your help.


I have this class written in Objective-C

@interface MySpecialManager <NSObject>

+ (MySpecialManager *)sharedInstance;
-(void)someFunctionWithParamOne:(NSString *)paramOne andParamTwo:(NSString *)paramTwo;
-(void)someFunctionWithParamOne:(NSString *)paramOne andParamTwo:(NSString *)paramTwo success:(void (^)(NSString *))success failure:(void (^)(NSError *error))failure;

@end

I have unit tests (in Swift) for the second function with the success/failure blocks but I am now trying to write unit tests for the first function. All this function does is call the second function. Therefore, I was thinking the best way to test this would be to just check that the second function does indeed get called and with the correct parameters. Therefore, I thought mocking/stubbing was the way to go forward but I am struggling to understand how exactly to unit test this.

From much Googling I read that creating my own Mock object would be the way to go forward so I have this now (written in Swift):

class MockMySpecialManager: NSObject, MySpecialManagerProtocol {

var functionOneWasCalled = false
var functionTwoWasCalled = false

func someFunctionWithParamOne(paramOne: String!, andParamTwo paramTwo: String!) {
    functionOneWasCalled = true
}

func someFunctionWithParamOne(paramOne: String!, andParamTwo paramTwo: String!, success: ((String!) -> Void)!, failure: ((NSError!) -> Void)!) {
    functionTwoWasCalled = true
}

If in my test though I initialise a MockMySpecialManager and call the first method, it won't call the second one as it just updates the boolean, correct? I could update the mock function to call the second but that feels like cheating and not a real unit test as its not testing my code. How can I test this?

I somehow (or so I think) need to set the manager to MySpecialManager.sharedInstace() , call the first method and then check if my second method was called on the mock.

Any help? What am I misunderstanding/where am I going wrong?

Your current MOC class is actually a complete replacement of the target class, so you aren't actually testing it at all.

If your MOC was a subclass of the target class instead, and only implemented the second method, then the test can call the first method and the MOC can verify that the second method was called.

Often you would use a mocking library to assist with this, and those libraries allow you different ways to do the same thing as above.

Alternatively you wouldn't MOC the target class, you would MOC all of its dependencies. Then your test checks that the dependencies are called appropriately and with the requisite parameters. Then your first and second method tests are the same setup but with slightly different expectations.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM