objective-c - 有没有办法在 XCTest 函数中模拟用户的输入?
问题描述
我有期望用户输入的方法
@implementation TeamFormation
- (void)run {
NSFileHandle *kbd = [NSFileHandle fileHandleWithStandardInput];
NSData *inputData = [kbd availableData];
NSString *option = [[[NSString alloc] initWithData:inputData
encoding:NSUTF8StringEncoding] substringToIndex:1];
NSLog(@"%@",option);
}
@end
然后我想通过一个测试用例来介绍这个方法
@interface TeamFormationTests : XCTestCase
@end
@implementation TeamFormationTests
- (void)testTeamFormation {
TeamFormation *teamFormation = [TeamFormation new];
[teamFormation run];
// emulate user's input here
}
@end
那么,如何在测试用例功能中模拟用户的输入呢?
解决方案
You have many options how to achieve this. Two obvious below.
Change run
to accept an argument
- (void)run
to- (void)runWithFileHandle:(NSFileHandle *)handle
- your app code can pass stdin filehandle
- your test code can pass handle to a file with desired input
Mock it with protocol
Create DataProvider
protocol:
@protocol DataProvider
@property(readonly, copy) NSData *availableData;
@end
Make NSFileHandle
to conform to this protocol:
@interface NSFileHandle (AvailableDataProvider) <DataProvider>
@end
Store an object implementing this protocol on TeamFormation
:
@interface TeamFormation : NSObject
@property (nonatomic, nonnull, strong) id<DataProvider> dataProvider;
- (NSString *)run;
@end
By default, use stdin file handle:
@implementation TeamFormation
- (instancetype)init {
if ((self = [super init]) == nil) {
return nil;
}
_dataProvider = [NSFileHandle fileHandleWithStandardInput];
return self;
}
- (NSString *)run {
NSData *inputData = [self.dataProvider availableData];
return [[[NSString alloc] initWithData:inputData encoding:NSUTF8StringEncoding] substringToIndex:1];
}
@end
Create TestDataProvider
in your test:
@interface TestDataProvider: NSObject<DataProvider>
@property (nonatomic, strong, nonnull) NSData *dataToProvide;
@end
@implementation TestDataProvider
- (instancetype)init {
if ((self = [super init]) == nil) {
return nil;
}
_dataToProvide = [NSData new];
return self;
}
- (NSData *)availableData {
return _dataToProvide;
}
@end
And use it in TestFormationTests
:
@implementation TeamFormationTests
- (void)testFormationRun {
TestDataProvider *dataProvider = [TestDataProvider new];
TeamFormation *formation = [TeamFormation new];
formation.dataProvider = dataProvider;
XCTAssertThrows([formation run]);
dataProvider.dataToProvide = [@"foo" dataUsingEncoding:NSUTF8StringEncoding];
XCTAssertEqualObjects([formation run], @"f");
dataProvider.dataToProvide = [@"bar" dataUsingEncoding:NSUTF8StringEncoding];
XCTAssertEqualObjects([formation run], @"b");
}
@end
推荐阅读
- c++ - 如何将 CPP 中的 OpenCV 与 Premake5 链接
- javascript - 当没有结果时,输入字段在 Vue 中失去焦点
- regex - Ruby Regex:字符串开头和结尾的空格
- pandas - 在 Pandas 中在一行中分配日、周和年列
- node.js - gulp.dest 挂起复制一个电子构建的应用程序(macoS)
- python - 当我在 Pandas DataFrame 中使用数据透视函数时,这个奇怪的数字是多少?
- mongodb - 使用 Express 在 MongoDB 中进行 $text 查询所需的文本索引
- python - 这个程序正在返回模块 os 没有战士游戏的属性
- typescript - 在浏览器中运行 typescript 编译器
- openshift - 在 OpenShift 中从命令行获取 pod 上次重新启动