swift 2中单元测试的存根方法

Posted

技术标签:

【中文标题】swift 2中单元测试的存根方法【英文标题】:Stubbing methods for unit testing in swift 2 【发布时间】:2015-08-26 14:10:57 【问题描述】:

我发现很难在 swift 结构中存根方法。我目前可以使用我将在下面解释的方式来做到这一点,但对我来说感觉不对,并希望对此发表意见。

我不使用任何第三方库进行存根,而是更喜欢覆盖我需要更改其结果的特定方法。在 swift 之前,我总是使用类 - 所以很容易继承和覆盖我需要在我的单元测试用例中模拟的方法。

现在我的大部分构造都是结构,因为它们实际上不需要是引用类型。但是我不能在我的测试用例中覆盖任何方法。我目前使用的协议扩展如下所述 -

protocol AProtocol 
  func a()
  func b() // This calls a()


extension AProtocol 
  func a()
     //Default implementation of a()
  
  func b()
     //Default implementation of b() which also calls a()
  


struct A:AProtocol 
  // Empty. struct A will be used by other classes/structs in the code

在我的测试用例中

struct TestA:AProtocol 
   func a() 
      Some mock implementation of a() so that b() can be tested
   

所以我的问题是 - 结构 A 没有真正需要通过协议来实现。其他任何类或结构都不会实现 AProtocol。但这是我可以模拟其单元测试方法的唯一方法。我认为关于协议扩展的 WWDC 会议也展示了这种单元测试方式,但基本上我不需要我的结构作为协议的实现。

有没有其他方法可以快速存根结构方法(不使用任何第三方库)?或者更好的方法来测试结构的方法。

【问题讨论】:

【参考方案1】:

我将成为不回答问题并探索您是否真的需要做您所要求的事情的人,恐怕。

我的问题是你是否真的需要模拟结构。对于非变异函数,设置结构并测试返回值。对于变异函数,检查之后的状态是否符合您的预期。

对于结构,除了修改之外通常不会产生副作用,因此无需准确跟踪调用了哪些其他函数。

可能与答案足够接近以提供一些帮助的位:

如果你真的在结构之外做一些有副作用的事情,我建议你将正在执行效果的对象或在可注入的对象上,以便通过仅 init 的额外测试,你可以注入一个替代的模拟对象来接收副作用调用。

【讨论】:

结构体具有非变异函数。考虑 a() 返回一个 ServiceProvider 实例。 b() 使用此实例来放置后端请求。现在我不希望 b() 在我的单元测试中实际使用 ServiceProvider 实例。相反,我希望覆盖 a() 以提供一个模拟实例,该实例只能提供预设响应 在向我指出差异后将“mock”更改为“stub”

以上是关于swift 2中单元测试的存根方法的主要内容,如果未能解决你的问题,请参考以下文章

单元测试术语的概述(存根与模拟,集成与交互)?

单元测试 - 存根 SqlDataReader

《单元测试的艺术》读书笔记----使用存根破除依赖

单元测试用例 - Swift 3.2

无论存根权限如何,带有 checkPermission 的 Apache shiro 单元测试都会通过

GAE的存根(用于单元测试)