Swift 中的单元测试 | IOS 故事板 |无法转换目标 c 中定义的视图控制器类

Posted

技术标签:

【中文标题】Swift 中的单元测试 | IOS 故事板 |无法转换目标 c 中定义的视图控制器类【英文标题】:UnitTest in swift | IOS Storyboard | Failed to cast viewcontroller class defined in objective c 【发布时间】:2017-05-23 15:09:31 【问题描述】:

所以我正在尝试为我的一个控制器类写一些测试用例,

    我的视图控制器在目标 c 中定义。 我正在快速编写测试用例。 我已将我的 viewcontroller 类包含在我的主要目标和测试目标中。 我还在测试和主要目标中添加了故事板。

在我的测试中,我试图从故事板加载视图控制器,下面是代码(此代码在我的 swift 类的正常项目中运行良好)

let storyboard = UIStoryboard.init(name: "Main", bundle: Bundle.init(for: self.classForCoder))
    let viewController:UIViewController = storyboard.instantiateViewController(withIdentifier: "loginViewController")
    print(viewController.classForCoder)
    print(type(of: viewController))
    let _ = viewController.view
    controller = viewController as! LoginViewController

打印输出

LoginView Controller 

__ABT_LoginViewController

我的代码的最后一行正在失败i.e

controller = viewController as! LoginViewController

我遇到的错误

Could not cast value of type '__ABT_LoginViewController' (0x600000053b30) to 'LoginViewController' (0x11e88de30).

需要你们的帮助

更新 因此,在遵循@dashandrest 的回答后,上述问题得到了解决,现在我面临新问题,我为测试用例创建了一个 TestAppdelegate 文件,在我的 TestAppDelegate 类中,我在编译整个代码后有这个语句 import "App-swift.h now它在 App-swift.h 文件中出现错误,提到无法导入模块 AppName,我的主要目标模块名称是 AppName,而测试目标模块名称是 AppNameTest,

#import "App-swift.h" 现在我在 App-swift.h 文件中遇到编译错误。

#if defined(__has_feature) && __has_feature(modules)
@import ObjectiveC; 
@import AppName; ///this line generate compile errror, module AppName not found 
@import XCTest;
#endif

更新

因此,我解决了我的应用程序中的多个问题,@DashAndRest 输入绝对可以帮助我识别这些问题,以下是我为了使事情正常进行而更正的事情。

    从测试目标中删除除测试用例之外的所有代码文件。 确保我的主要目标和测试目标有单独的模块名称。 确保我的 Pods 文件也为我的测试目标安装了库。 为了安全起见,用 Swift 编写测试用例,这样我就不需要在测试用例中包含 Appname-swift.h。 使用@testable import AppModuleName(由@DashAndRest 建议)

【问题讨论】:

现在检查解决方案... 【参考方案1】:

这不是必需的:

3 我已将我的 viewcontroller 类包含在我的主要目标和测试目标中。 4 我还在测试和主要目标中添加了故事板。

尝试取消选中视图控制器和情节提要的测试目标。 然后在您的测试文件中只包含主要目标:

@testable import Your-Main-Target-Name

更新

App-swift.h 仍然令人困惑。

但如果你想测试LoginViewController,这里是解决方案:

将Bridging Header 添加到您的主要AppName 目标中,并将所有objective-c 类导入其中,例如:

#ifndef AppName_Bridging_Header_h
#define AppName_Bridging_Header_h

#import "LoginViewController.h"

#endif 

在此之后,您的 LoginViewController 类将可供所有其他 swift 类使用,包括测试目标。

在测试目标中添加像LoginVCTests.swift这样的新文件,并在其中添加以下代码-

import XCTest
@testable import AppName

class LoginVCTests: XCTestCase 
  func testSomeLogic()  
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let viewController:UIViewController =     storyboard.instantiateViewController(withIdentifier: "loginViewController") as! LoginViewController
    print(viewController.classForCoder)
    print(type(of: viewController))
    let _ = viewController.view
    //test on viewController
  

希望这能解决您的问题!

【讨论】:

你摇滚,但这在 LoginViewController 的情况下工作正常,但在我的登录视图控制器管理器类的情况下它不起作用,即 LoginDataManager,它给我编译时错误,找不到我的单元测试类中的 LoginDataManager 类,因为我也从测试目标中删除了 LoginDataManager。 您可以为您的LoginDataManager 放置代码吗?只是结构;导入 testable 后,主目标内的每个类都应可用于测试目标! 所以这有点奇怪,在清理/构建 LoginDataManager 问题之后,现在它显示新问题,我为测试用例创建了一个 TestAppdelegate 文件,在我的 TestAppDelegate 类中我有这个语句@987654330 @ now 在编译整个代码后,它在 App-swift.h 文件中出现错误,提到无法导入模块 AppName,我的主要目标模块名称是 AppName 而测试目标模块名称是 AppNameTest, 那是什么? 刚刚在我上面的评论中添加了更多细节,非常感谢你的帮助:)

以上是关于Swift 中的单元测试 | IOS 故事板 |无法转换目标 c 中定义的视图控制器类的主要内容,如果未能解决你的问题,请参考以下文章

应用于控制器的背景未应用于故事板swift中的表格视图单元格

为啥故事板弹出框在 Swift 中的设备上不起作用?

使用自定义表格视图单元格中的故事板segue

swift in UI test(测试UITableView中的单元格数)

swift 没有故事板的iOS项目。 AppDelegate.swift

XCode故事板中的自定义静态表格单元格?