在Swift中使用内联预处理宏

3
背景:我想使用 XCTest 测试私有方法,因此我正在寻找一种优雅的解决方案将私有方法暴露给我的 XCTestCase 类。
免责声明:有些人认为测试类的内部是根本错误的。但在实践中,当测试失败时,测试私有方法可以使追踪问题变得更加容易。
Swift 的私有函数是文件私有的,并且私有确实意味着私有,因此没有办法将私有函数暴露给其他文件。使用预处理器宏,可以通过公共函数仅为一个构建配置公开私有功能。例如,我为我的测试配置设置了一个 TEST 编译标志,我的测试方案就可以使用它。
到目前为止,这是我拥有的最佳解决方案,但它需要针对每个需要测试的私有函数使用烦人的样板代码:
在 ClassThatNeedsTesting.swift 中:
class ClassThatNeedsTesting {
   #if TEST
   func publicAccessToPrivateFunctionThatNeedsTesting() -> Bool {
      return self.privateFunctionThatNeedsTesting()
   }
   #endif

   private func privateFunctionThatNeedsTesting() -> Bool {
      return true;
   }
}

在 TestClass.swift 文件中:
class TestClass: XCTestCase {
   func testExample() {
      XCTAssert(ClassThatNeedsTesting().publicAccessToPrivateFunctionThatNeedsTesting());
   }
}

但是有没有使用内联预处理宏来简化这个过程的方法呢?这正是我想要的,但它不能编译,所以我才会问这个问题:

在ClassThatNeedsTesting.swift文件中:

class ClassThatNeedsTesting {
   #if TEST private #endif func privateFunctionThatNeedsTesting() -> Bool {
      return true;
   }
}

在 TestClass.swift 文件中:
class TestClass: XCTestCase {
   func testExample() {
      XCTAssert(ClassThatNeedsTesting().privateFunctionThatNeedsTesting());
   }
}

如果没有其他方法,也许有一个更简单的解决方案?
1个回答

3

使用Swift 2.0中新增的@testable关键字:

@testable import MyModule

class TestClass: XCTestCase {
   func testExample() {
      XCTAssert(ClassThatNeedsTesting().privateFunctionThatNeedsTesting());
   }
}

来自 Xcode 7 发布说明

可测试性。有了可测试性,您现在可以编写 Swift 2.0 框架和应用程序的测试,而无需使所有内部例程公开。在测试源代码中使用 @testable import {ModuleName},使所有公共和内部例程可供 XCTest 目标使用,但不可供其他框架和应用程序目标使用。

是否应该测试私有方法是一个热门话题。请参见此处的讨论(英文)(英文)以及(英文)


2
这个不起作用。你引用的苹果文档指出:“在测试源代码中使用@testable导入{ModuleName},以使所有公共和内部例程可供XCTest目标使用。” @testable仅适用于公共和内部例程,而不适用于私有例程。 - kev
只是赞同Kev的意见,因为我也遇到了同样的问题。在我的测试中,当调用私有方法时,我得到了以下错误:使用未解决的标识符“PrivateMethodNameHere”。请注意,如果这是Obj-C,您可以调用私有方法,并在此处讨论:https://dev59.com/SWjWa4cB1Zd3GeqPpEYl - xdeleon
你会如何在Objective-C中使用@testable? 你能否将你的应用程序作为模块导入到Objective-C中?请原谅我的无知 - 在这个话题上很难找到好的信息! - shmim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接