Swift、访问修饰符和单元测试

Posted

技术标签:

【中文标题】Swift、访问修饰符和单元测试【英文标题】:Swift, access modifiers and unit testing 【发布时间】:2014-07-28 11:48:25 【问题描述】:

我刚刚升级到 Xcode 6 beta 4,其中 Swift 编译器现在支持 access modifiers。

这给我带来了问题,因为我的单元测试现在无法编译(由于类不是公开的)。

简单的解决方案当然是将所有测试的类公开,但这感觉像是一种 hack(我个人的偏好是即使在非公开类上也编写单元测试)。

在 .NET 和 Java 中,您通常可以允许单元测试程序集级别(或 Java/OSGi 中的包级别)从单元测试程序集访问被测程序集。我不明白如何在 Swift 中做类似的事情。我真的必须公开我的所有课程以对它们进行单元测试吗?

【问题讨论】:

我并不介意,因为通常我只想测试公共 API。测试每个类和每个方法都是一种浪费。 最终这是一个哲学问题,并且有不同的意见/策略。我不会测试所有东西,但我会尽量保持我的公共 API 尽可能小。我更喜欢类似 IoC 的解决方案,但在这种应用程序中,这感觉完全是矫枉过正。 【参考方案1】:

这是一个已知问题,在 Beta 4 发行说明中有所提及。在提供更多信息之前,您可能希望推迟更改设计。

我们知道我们的访问控制设计不适合单元测试(这在发行说明中),我们正在评估情况,看看我们能做些什么。

-- 克里斯·拉特纳

访问控制系统的一个限制是单元测试不能与应用程序中的类和方法交互,除非它们被标记为公共。这是因为单元测试目标不是应用程序模块的一部分。

-- Xcode beta 4 发行说明

https://github.com/ksm/SwiftInFlux#limitations-of-current-access-control-design

【讨论】:

感谢您的信息!我现在将所有内容都公开,让我们希望在下一个 Xcode 版本中在这方面有所改进。 克里斯..我在以后的 BETA 中找不到任何更新..Apple 刚刚发布了一个使单元测试变得困难的产品吗?! 我自己也没有听说过。如果他们没有在 1.0 中解决这个问题,那就太可惜了。也许他们会在 Xcode 6.1 中与 Yosemite 一起发布。【参考方案2】:

使用 Swift 2,您现在可以测试您的课程,而无需将其标记为公开。您只需要使用关键字@testable,编译器就会负责。

从What's new in Xcode WWDC 2015 滑动:

【讨论】:

【参考方案3】:

您可以将目标中的源文件添加到测试目标中。然后它们将成为您的测试目标的一部分,您将能够访问它们。

【讨论】:

试过了,但后来它们属于另一个模块(测试模块)。因此,测试创建的类的实例不能转换为应用创建的类的实例。 @Krumelur 如果您对所有源文件都这样做,这会不会有问题? 好吧,既然这些类是分开的(与 ObjC 不同),我可以预见很多问题。对我来说最直接的一个是 CoreData 托管类。 @Krumelur 嗯,这可能是个问题。 好吧,我很务实,并且公开了我的“内部”API :)【参考方案4】:

我认为我有一个比公开所有内容更好的解决方案。只需让 StoryBoard 成为测试目标的成员,就像使用所有 ViewController 一样。然后使用您的测试包而不是使用 nil 或主包在您的测试类中创建 StoryBoard。查看my post here 获取示例代码。

var storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: NSBundle(forClass: self.dynamicType))
vc = storyboard.instantiateViewControllerWithIdentifier("LoginVC") as LoginViewController
vc.loadView()

【讨论】:

以上是关于Swift、访问修饰符和单元测试的主要内容,如果未能解决你的问题,请参考以下文章

typescript 访问修饰符和 javascript 访问修饰符有啥区别?在使用打字稿时我应该更喜欢哪一个?

Java基础知识回顾之二 ----- 修饰符和String

Java基础知识回顾之二 ----- 修饰符和String

JAVA中的访问修饰符和包

访问修饰符和继承

Java修饰符和String