如何使用 Typhoon 为集成测试注入假的、存根的或模拟的依赖项

2024-04-28

我正在尝试使用 KIF 编写集成测试。我的问题是:

如何为特定视图控制器注入存根、模拟或虚假依赖项?

每个使用数据模型、http 客户端、存储管理器等依赖项的视图控制器都来自 ModelAssembly、ApplicationAssembly、ManagerAssmebly。

在故事板上,对于登录视图,我有一个关键路径,包含值“login ViewController”。

创建视图控制器:

ViewControllersAssembly.h

@interface ViewControllersAssembly : TyphoonAssembly
@property (nonatomic, strong) ModelAssembly *modelAssembly;

- (id)loginViewController;
@end

ViewControllersAssembly.m

@implementation ViewControllersAssembly
- (UIViewController *)loginViewController {
return [TyphoonDefinition withClass:[LoginViewController class] configuration:^(TyphoonDefinition *definition) {
    [definition injectProperty:@selector(userModel) with:[self.modelAssembly userModel]];
}];

}

UserModel 有登录方法

- (RACSingnal*)loginWithEmail:(NSString*)email password:(NSString*)password;

现在在集成测试目标中我有这样的类:

登录测试.h

@interface LoginTests : KIFTestCase
@property (nonatomic, strong) UserModel *fakeUserModel;
@end

登录测试.m

@implementation LoginTests

- (void)beforeAll {
    self.fakeDataModel = [self mockDataModel];
}

- (void)testLogin {
    [self.fakeDataModel mockNextResponse:[RACSignalHelper getGeneralErrorSignalWithError:[[NSError alloc] initWithDomain:@"http://some.com" code:452 userInfo:nil]]];
    [tester waitForViewWithAccessibilityLabel:@"loginScreen"];

    [tester enterText:@"[email protected] /cdn-cgi/l/email-protection" intoViewWithAccessibilityLabel:@"emailAdress"];
    [tester enterText:@"asd123" intoViewWithAccessibilityLabel:@"password"];
    [tester tapViewWithAccessibilityLabel:@"loginButton"];

    [tester tapViewWithAccessibilityLabel:@"OK"];
    // for example error code 542 we should display alert with message "User Banned"
    // now somehow check that UIAlertView localizedDescription was "User Banned" 
}

- (FakeUserModel *)mockUserModel {
    ModelAssembly *modelAssembly = [[ModelAssembly assembly] activate];
    TyphoonPatcher *patcher = [[TyphoonPatcher alloc] init];
    [patcher patchDefinitionWithSelector:@selector(userModel) withObject:^id{
        return [FakeUserModel new];
     }];

    [modelAssembly attachDefinitionPostProcessor:patcher];
    return [modelAssembly userModel];
}

假用户模型是覆盖用户模型类的类,增加了为下一个调用的请求存根响应的可能性。

该解决方案不起作用。

我应该如何以及在哪里传递 FakeUserModel?

1)我想访问注入的实例

2)注入的实例必须是FakeUserModel类型,仅在集成测试目标中。

3)我不想修改集成测试的生产代码。


单元测试

如果您希望用测试替身替换给定类的所有依赖项,从而与协作者隔离地测试一个类,这将是一个单元测试。只需实例化一个测试实例,将测试替身(模拟、存根等)作为协作者传递即可。

集成测试

如果您希望使用测试替身修补程序集中的一个或多个实例,以使系统进入集成测试所需的状态,Typhoon 提供了多种方法。

You can 修补一个组件如下:

MiddleAgesAssembly* assembly = [[MiddleAgesAssembly assembly] activate];

TyphoonPatcher* patcher = [[TyphoonPatcher alloc] init];
[patcher patchDefinitionWithSelector:@selector(knight) withObject:^id{
    Knight* mockKnight = mock([Knight class]);
    [given([mockKnight favoriteDamsels]) willReturn:@[
        @"Mary",
        @"Janezzz"
    ]];

    return mockKnight;

}];

[assembly attachPostProcessor:patcher];

Knight* knight = [(MiddleAgesAssembly*) factory knight]

有关此方法的更多信息可以在集成测试 https://github.com/appsquickly/Typhoon/wiki/Integration-Testing#in-this-section---用户指南的部分。

模块化

或者,您可以模块化您的程序集,并使用子类或替代实现来激活,这提供了某些类的另一种实现,例如:

UIAssembly *uiAssembly = [[UIAssembly new] 
    activateWithCollaboratingAssemblies:@[
        [TestNetworkComponents new], //<--- Patched for testing
        [PersistenceComponents new]];

SignUpViewController* viewController = [uiAssembly signUpViewController];

有关此方法的更多信息可以在模块化部分 https://github.com/appsquickly/Typhoon/wiki/Modularizing-Assemblies用户指南。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 Typhoon 为集成测试注入假的、存根的或模拟的依赖项 的相关文章

  • 强制向扬声器发出音频警报

    我有一个小应用程序 在此应用程序中 扬声器每隔我设置的特定时间就会发出噪音 现在 我希望即使设备中插入了耳机插孔 它也能通过内置扬声器发出噪音 我怎样才能做到这一点 您可以尝试以下代码在扬声器上播放代码 另请检查this http uiha
  • 使用UDID创建唯一的用户身份

    我正在开发一个 iPhone 应用程序 它与服务器通信以存储和交换数据 因为我想让它尽可能简单 所以我想避免用户帐户的注册 或者也可能使用密码 是否有可能 并且允许 获取 iPhone 设备的 UDID 并制作例如 它的 MD5 哈希值 我
  • 原生插入符位置 macos cocoa

    我希望能够使用 cocoa 或 appleScript 获取 Mac High Sierra 中任何应用程序内的全局插入符位置 我已经使用 NSEvent 来获取键盘和鼠标挂钩 但是有没有办法获取插入符位置挂钩 插入符号与鼠标位置不同 它会
  • 我应该在我的 iOS Objective-C 项目中使用它吗?

    Xcode 中的 构建设置 中的 Mach O 类型是什么 应该设置什么 它有这些选项 可执行文件 动态库 捆绑包 静态库 可重定位对象文件 自从我将其从可执行文件更改为静态库以来 我遇到了错误 Apple Mach O 链接器错误组 我的
  • NSString 上的 stringWithFormat 与 initWithFormat

    我想知道以这种方式声明 NSString 有什么区别 例如缺点和 或优点 NSString noInit NSString stringWithFormat lolcatz d i 与以下相反 NSString withInit NSStr
  • 动态高度 UITableViewCell 内的动态高度 UICollectionView

    我有一个水平的UICollectionView固定到 a 的所有边缘UITableViewCell 集合视图中的项目是动态调整大小的 我想让表视图的高度等于最高集合视图单元格的高度 视图的结构如下 UI表格视图 UITableViewCel
  • UITableViewCell 内的 UIPageViewController

    嘿我想问如何在 UITableViewCell 内实现 UIPageViewController 我一直在阅读周围的内容 但到目前为止似乎对任何尝试的人都不起作用 我希望得到一些提示 不需要完整的答案 谢谢 目前还不清楚你到底想做什么 但让
  • UIView 框架更改时阴影层不调整大小

    问题图像截图 https i stack imgur com cyc5o png class ViewController UIViewController var shadow UIView override func viewDidLo
  • 如何使用 PKAddPassButton 创建“添加到苹果钱包”按钮以进行本地化通行证

    在我的 iOS 项目中 我有一个屏幕 允许用户创建苹果通行证并将其添加到钱包中 Apple 建议使用 PKAddPassButton 创建 添加到苹果钱包 按钮 当我尝试使用以下代码创建苹果通行证时 let passButton PKAdd
  • ARKit 演示在 iPhone 6/iPhone 6 Plus 上崩溃

    我正在与ARKit功能 https developer apple com videos play wwdc2017 602 最近发布了主要的 iOS 版本 但我遇到了错误崩溃failed assertion MTLRenderPassDe
  • Cocoapods 测试链接器错误

    每当我构建测试目标 Xcode 生成的标准目标 时 构建都会失败并出现神秘错误 framework not found Pods AppName AppNameTests 我认为这意味着无法找到为我的测试生成的 pod 目标 我的 podf
  • 我可以通过 PresentFeedDialogModallyWithSession 传递给 FBWebDialogs 的完整合法参数集是什么

    我查看了 Facebook 上的示例代码 这里 https developers facebook com docs howtos feed dialog using ios sdk https developers facebook co
  • 无法在 iOS UIWebView 中加载完整的 Facebook 评论插件

    我有一个简单的ViewController在 UIWebView 中加载 FB 评论插件 implementation ViewController void viewDidLoad super viewDidLoad UIWebView
  • 具有自签名证书的 Alamofire / ServerTrustPolicy

    我想使用 Alamofire 通过带有自签名证书的 https 连接与我的服务器进行通信 我的环境在本地主机上运行 我尝试连接 但响应始终如下所示 Success false Response String nil 我用下面的代码完成了它
  • 如何使用 Swift Package Manager 将 SwiftLint 与 iOS 应用程序集成?

    我正在使用 Xcode 11 beta 5 创建一个新的 iOS 应用程序 并且我想使用 Swift Package Manager 而不是 CocoaPods 来管理依赖项 使用 SwiftLint 和 CocoaPods 时的常见模式是
  • UITableView 无法一直滚动到底部[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我只是好奇 我做了一些UITable
  • 使用 iOS swift AVPlayer 在横向模式下不全屏

    我将视频视图设置为全屏 然而 在模拟器中玩时 它并没有全屏运行 此问题仅适用于 iPad 不适用于 iPhone 这是我的代码 override func viewDidAppear animated Bool super viewDidA
  • iOS AVCaptureVideoDataOutput 消耗太多内存

    我在用AVFoundation使用iPhone相机捕获视频的框架 我的代码 self session AVCaptureSession alloc init self output AVCaptureVideoDataOutput allo
  • 如何为移动应用程序创建无密码登录

    我有兴趣在移动应用程序和 API 之间构建某种无密码登录 假设我可以控制两者 动机是必须登录对用户来说非常烦人并且存在安全风险 例如 用户将重复使用现有密码 我希望用户能够立即开始使用该应用程序 我想知道是否有一些可行的技术 例如 在移动设
  • Facebook iOS 选择好友表空白

    我正在尝试将 选择的朋友 添加到我的 iOS 应用程序中 我设置了登录视图 登录后 我打开朋友选择器 但它显示为空白 我看到带有 完成 和 取消 按钮的表 但表中没有加载任何朋友 IBAction selectFriendsButtonAc

随机推荐

  • 使用不带标签的 Core.Std.List.fold_left

    我正在尝试 Core 的List fold left List fold left a Core Std List t gt init b gt f b gt a gt b gt b
  • 流量类型问号?

    对使用 感到困惑在流动中 据我所知 感谢参数之前或之后的流类型问号 https stackoverflow com questions 47314749 flow type question mark before or after par
  • 来自 StreamReader 的原始文件字节,幻数检测

    我试图区分 文本文件 和 二进制 文件 因为我实际上想忽略具有 不可读 内容的文件 我有一个文件 我认为它是 GZIP 存档 我试图通过检测幻数 文件签名来忽略此类文件 如果我在 Notepad 中使用十六进制编辑器插件打开文件 我可以看到
  • 无法使用“in”运算符在中搜索“_id”

    我正在尝试使用 mongoose 和express 来获取现有的用户文档 但我只得到这个 webroot api domain com production node modules mongoose lib document js 162
  • 删除 JavaScript 中的不间断空格

    我无法从字符串中删除空格 首先我要转换div to text 删除标签 有效 然后我尝试删除 nbsp 字符串的一部分 但它不起作用 知道我做错了什么 newStr myDiv text newStr newStr replace nbsp
  • 当我已经在Ubuntu上安装了nodejs 8时,还可以安装NVM吗?

    我已经安装了nodejs 8 我无法使用角度1运行karma测试 正如Karma官方网站上指定的那样Note Karma currently works on Node js 0 10 0 12 x 4 x 5 x 6 x and 7 x
  • 在准备好的语句中设置数组,抛出 java.sql.SQLFeatureNotSupportedException

    我有一个字符串列表 我想将其设置为准备好的语句中的参数 这里的问题和答案看起来很简单 如何使用数组列表作为准备好的语句参数 https stackoverflow com questions 17842211 how to use an a
  • Rails 3 session_store 域 :all 的作用是什么?

    更新了问题以使其更清楚 据我所知 您可以设置 session store 的域以在子域之间共享会话 如下所示 Rails application config session store cookie store key gt my key
  • Android 库项目依赖于其他库项目

    由于各种原因 我遇到的情况是 我在小型独立的 android 库项目中存在多个应用程序组件 这些组件正在编译为 aars 在某些情况下 这些会被推送到 Maven 存储库并以这种方式使用 这很好 一切都很好 在其他情况下 这些 aar 需要
  • ASP.NET MVC 4 中的全局变量

    我目前正在构建一个 ASP Net MVC 4 SAAS 应用程序 C 并且一直致力于设计计划 我的意思是如果客户选择Plan A他们应该有权访问一些东西 如果他们选择的话Plan B他们可以接触其他人等等 我坚持的部分是与所有操作共享帐户
  • Vuejs 2 将 prop 对象传递给子组件并检索

    我想知道如何使用 props 和检索将对象传递给子组件 我了解如何将其作为属性来执行 但是如何传递对象并从子组件中检索对象 当我从子组件中使用 this props 时 我收到未定义或错误消息 父组件
  • 更改 TextField Material-UI v1 的 onHover 颜色

    我无法通过覆盖类名来更改 TextField 的 onHover 颜色 我怎样才能做到这一点 我正在使用材质 UI v1 https github com callemall material ui tree v1 beta https g
  • 卡住。如何将这 3 个文本居中并间隔开? [复制]

    这个问题在这里已经有答案了 尝试向左 居中 向右移动 3 段文本 尝试使用 CSS 但我陷入困境 Thanks 您可以使用 flex 并将 justify content 设置为 space Between text container d
  • sails.js 嵌套模型

    在 sails js 0 10 中我尝试执行以下操作 user js module exports attributes uuid type string primaryKey true required true profile firs
  • 如何添加将 WC_Product_Variable 扩展到购物车的自定义 WooCommerce 产品类型

    我创建了一个基于内置变量产品类型的自定义 WooCommerce 产品类型 我希望拥有特定于我的产品类型的产品变体以及自定义特征和字段 这一切都在管理和我的自定义前端产品页面模板中正常工作和显示 这是我定制的产品 供参考 add actio
  • Java 轮询网络连接

    我正在用 Java 编写一个程序 在一个线程上打开 256 个网络连接 每当套接字上有任何数据时 我都应该读取它并处理它 目前 我正在使用以下方法 while true do iterate over all network connect
  • 如何测试 django 模板块的使用?

    我想做以下事情 if appnav hr div ul class tabs block appnav endblock ul div endif 但是 测试继承链中模板当前使用的块似乎不起作用 还有其他条件可以做到这一点吗 模板语言并不能
  • 使用 AppleScript 设置窗口位置

    我正在尝试使用 AppleScript 设置 Messages app 聊天窗口的位置 tell application System Events set position of window 1 of application Messa
  • 登录时出现quickblox错误,android

    我正在使用 Quickblox 在 Android 平台上进行聊天 并使用 facebook 身份验证 我这样做这些步骤 1 QBSettings getInstance fastConfigInit 2 QBAuth createSess
  • 如何使用 Typhoon 为集成测试注入假的、存根的或模拟的依赖项

    我正在尝试使用 KIF 编写集成测试 我的问题是 如何为特定视图控制器注入存根 模拟或虚假依赖项 每个使用数据模型 http 客户端 存储管理器等依赖项的视图控制器都来自 ModelAssembly ApplicationAssembly