如何使用 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 为集成测试注入假的、存根的或模拟的依赖项 的相关文章

  • cordova-plugin-whitelist 适用于 Android,但不适用于 iOS (Phonegap Build)

    我正在开发一个用 Cordova 封装并使用 Phonegap Build 构建的 JavaScript 应用程序 我们包括cordova plugin whitelist来自我们构建中的 npm 并添加了
  • 在 iOS 中管理和解除多个视图控制器

    我是一名 iPhone 新手程序员 在开发我的第一个游戏 应用程序时 我为自己提出了一个问题 创造了一个问题 我对此进行了研究 并认为我已经看到了答案 但我不明白如何使它们适用于我的应用程序 我有一个游戏 有几个视图控制器 欢迎 玩 高分
  • Swift 中的弹出视图

    我有一个弹出视图 没有选项卡栏 它弹出到带有选项卡栏的视图控制器 在带有选项卡栏的视图控制器中 我设置了一个单击按钮 以便弹出视图控制器 IBAction func PopUpClicked sender UIButton gt Void
  • 从 Plist 中存储和检索 [重复]

    这个问题在这里已经有答案了 可能的重复 iOS 在 plist 文件中存储两个 NSMutableArray https stackoverflow com questions 6070568 ios store two nsmutable
  • iOS:弃用 AudioSessionInitialize 和 AudioSessionSetProperty

    我对 Objective C 很陌生 正在尝试更新一些大约 3 年前的代码以与 iOS 7 一起使用 有两两个实例AudioSessionSetProperty and AudioSessionInitialize出现在代码中 1 void
  • 使用 Push Transition 效果更改 RootViewcontroller

    在我的iOS应用程序中 我需要更改应用程序之间窗口的rootviewController 因此 当我动态更改我的rootviewcontroller时 它会在更改之前轻拂视图 但我想要的是在更改rootviewcontroller时提供平滑
  • iOS App布局错误,调用状态栏

    在主动通话和应用程序布局期间面临状态栏问题 我正在使用自动布局 当我运行应用程序 然后开始通话时 一切正常 UI 会随着状态栏的更改而正确缩放 但是 如果我首先开始通话 然后运行应用程序 应用程序屏幕会移动到底部 20pt 就像它们对新状态
  • 如何在我的 iOS 项目中添加和执行 .sql 文件?

    我找到了很多关于在 iOS 中使用 SQLite 数据库的教程 但没有找到任何直接引用 sql 文件的内容 谁能告诉我如何将现有的 SQL 数据库链接到我的应用程序 编辑 这是一个 MySQL 转储 我们有一个基于浏览器的抽认卡程序 现在我
  • 对 UIImage 进行方形裁剪,导致图像拉伸

    当尝试执行 UIImage 的中心裁剪时 我得到以下结果 左侧是原始图像640 1136 右边是适合正方形的裁剪图像UIImageView at 320 320 turns to 我对比率元素进行了相当多的修改 以便它可以正确检测要修剪的量
  • 尝试从独立的 Apple Watch 应用发出网络请求

    当应用程序是独立应用程序时 Apple Watch 是否无法进行网络通话 即使手表已连接到 iPhone 我正在使用新的独立应用程序目标 它没有附带可以发出 WatchConnectivity 请求的配对 iOS 应用程序 我十有八九收到
  • 在 iOS 中录制音频并永久保存

    我制作了 2 个 iPhone 应用程序 可以录制音频并将其保存到文件中并再次播放 其中之一使用 AVAudiorecorder 和 AVAudioplayer 第二个是苹果的在这里说话 http developer apple com l
  • 如何从 NSString 中删除十六进制字符

    我面临一个与字符串中的某些十六进制值相关的问题 我需要从字符串中删除十六进制字符 The problem is when i print object it prints as BLANK line And in debug mode it
  • 从 Core Data、iOS 获取最后插入的项目

    有没有办法获取核心数据数据库中最后插入的项目 这将返回最后插入的对象 setFetchLimit 1 和 setFetchOffset 所有条目数 1
  • 在WKWebview中设置useragent

    如何在 WKWebView 中设置自定义用户代理字符串 我正在尝试嵌入我的应用程序的版本 以便我的服务器端可以看到可用的功能 我找到了以下方法 let userAgent MyApp 1 33 7 request setValue user
  • 在模拟器中运行应用程序时删除本地通知的 iOS 权限警报

    我正在尝试编写验收测试KIF https github com kif framework KIF在一个很早就要求本地通知权限的应用程序上 不幸的是 由于 iOS 模拟器安全原因无法使用 KIF 自动接受 iOS 权限警报 https gi
  • Objective-c中的贝塞尔曲线算法

    比我聪明的人可以看一下这个吗 我正在尝试实现我发现的贝塞尔曲线算法here http webtweakers com swag GRAPHICS 0074 PAS html在 Objective c 中 输出是错误的 我想我正确地转换了代码
  • 如何在ios中以编程方式添加水平间距和垂直间距?

    我在 ios 8 中创建了一个应用程序 因为我有 4 个可垂直使用的标签 它应该在某些条件下更改位置 所以我已禁用自动布局并以编程方式设置约束 现在的问题是 我可以设置水平和垂直位置 宽度和高度的约束 但我找不到任何方法来添加标签之间的水平
  • 如何在 EKRecurrenceRule 中设置一周中某一天的数组?

    我想在用户选择的特定日期每周添加事件 可以是一个或多个 也可以是一整天 我将用户选择的日期值存储在模型类变量中 但是 当我添加事件并选择日期时 假设今天是星期一 我选择星期二和星期三并保存 然后我查看周一和周三添加的 iPhone 日历 我
  • 增加 NSData 的长度

    基本上 我有一个 46 个字符的 NSString 我将其转换为 NSData 我需要将字符串填充到 48 个字符 仅在 NSString 末尾添加 是行不通的 所以 我只是使用以下方法增加了 NSData 的长度 NSString str
  • 如何在内存中存储分子?

    我想将分子存储在内存中 这些可以是简单的分子 Methane CH4 C H bond length 108 7 pm H H angle 109 degrees But also more complex molecules like p

随机推荐

  • 使用不带标签的 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