简体   繁体   English

在Swift单元测试中模拟Objective-C代码

[英]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 我有这个用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. 我对具有成功/失败块的第二个功能进行单元测试(在Swift中),但是我现在尝试为第一个功能编写单元测试。 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): 从很多谷歌搜索中,我读到创建自己的Mock对象将是前进的方式,所以现在有了(用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? 如果在测试中虽然我初始化了MockMySpecialManager并调用了第一个方法,则它不会调用第二个方法,因为它只是更新了布尔值,对吗? 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. 我以某种方式(或我认为)需要将管理器设置为MySpecialManager.sharedInstace() ,调用第一个方法,然后检查是否在模拟中调用了第二个方法。

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. 您当前的MOC类实际上是目标类的完整替代品,因此您实际上根本没有对其进行测试。

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. 如果您的MOC是目标类的子类,并且仅实现了第二个方法,则测试可以调用第一个方法,而MOC可以验证是否调用了第二个方法。

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. 或者,您将不MOC目标类,而是将其所有依赖项MOC。 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. 然后,您的第一方法测试和第二方法测试是相同的设置,但期望值稍有不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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