2

我使用 XCGLogger 已经有一段时间了,但是在将我的应用程序转换为 swift 3.0 之后,我在测试目标中遇到了问题。

我的 AppDelegate 类文件中有以下内容。这将创建一个全局变量log,例如,我可以通过调用在我的应用程序中的任何位置使用它log?.info("foo")

在迁移到 swift 3 之前,这也适用于测试目标,但现在如果我尝试log?.info("foo")在测试目标中使用,则会出现链接错误。

AppDelegate 代码

import XCGLogger

// USE_XCGLOGGER is set for debug but not for release

#if USE_XCGLOGGER
let log: XCGLogger? = {
  // Setup XCGLogger
  let log = XCGLogger.default      
  return log
}()
#else
let log: XCGLogger? = nil
#endif

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
 ...
}

测试目标中的类

import XCTest
@testable import OurLatitude

class ApiAccessTests: XCTestCase {

    override func tearDown() {
        super.tearDown()
        log?.info("foo")
    }

}

链接错误

undefined symbols for architecture x86_64:
  "XCGLogger.XCGLogger.(info (@autoclosure () -> Any?, functionName : Swift.StaticString, fileName : Swift.StaticString, lineNumber : Swift.Int, userInfo : [Swift.String : Any]) -> ()).(default argument 4)", referenced from:
      OurLatitudeTests.ApiAccessTests.tearDown () -> () in ApiAccessTests.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
4

1 回答 1

3

我使用 Carthage,我的单元测试设置是Host Application : None.

我想,框架没有添加到单元测试目标中,我是对的。所以我已经XCGLogger.framework从 carthage 文件夹添加到 Link Binary with Libraries in Build Phase。然后我还在运行脚本中添加了框架

在此处输入图像描述

这解决了我得到的错误,我开始得到一个新的错误

Ambiguous reference to member 'log'

然后创建一个一次性类来初始化XCGLogger解决它

我在这里创建了一个拉取请求,希望他能合并它....

https://github.com/DaveWoodCom/XCGLogger/pull/188/files

与单元测试一起使用。[在 Carthage 或手动框架安装后]

确保将 XCGLogger.framework 添加到单元测试目标的构建阶段 -> 将二进制文件与库链接。

我还添加了一个运行脚本以确保从 Carthage 文件夹中复制框架。

如果您的单元测试的宿主应用程序设置为 None 并且您的应用程序的类正在使用XCGLogger,您将看到如下错误

Ambiguous reference to member 'log' 发生这种情况是因为 XCTest 正在逐一运行您的单元测试,并且它无法访问您的 AppDelegate 文件中的 XCGLogger 构造函数。因此,您的一次性 init 不存在,并且无法找到正确的引用。

为了解决这个问题,你需要一个一次性的 init 方法来构建你的XCGLogger

在您的测试目标中创建一个新类,确保它被命名TestSetup

import XCGLogger

let log: XCGLogger = {
    // Setup XCGLogger
    let log = XCGLogger.default

    return log
}()


class TestSetup: NSObject {
    override init() {

    }
}

然后转到您的测试目标信息设置并添加一个新行Principal class和 Value will be YourTestTargetName.TestSetup,有关详细信息,请参阅如何在执行任何 XCTest 之前运行一次性设置代码

这应该可以解决问题....

于 2017-03-27T21:01:46.867 回答