有什么方法可以模拟用户在 XCTest 函数中的输入吗?
Is there any way to emulate user's input in XCTest function?
我有需要用户输入的方法
@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
那么,如何在测试用例函数中模拟用户的输入呢?
您有多种选择来实现这一点。下面两个很明显。
更改 run
以接受参数
- (void)run
到 - (void)runWithFileHandle:(NSFileHandle *)handle
- 您的应用代码可以传递标准输入文件句柄
- 您的测试代码可以将句柄传递给具有所需输入的文件
用协议模拟它
创建 DataProvider
协议:
@protocol DataProvider
@property(readonly, copy) NSData *availableData;
@end
使NSFileHandle
符合这个协议:
@interface NSFileHandle (AvailableDataProvider) <DataProvider>
@end
在 TeamFormation
上存储实现此协议的对象:
@interface TeamFormation : NSObject
@property (nonatomic, nonnull, strong) id<DataProvider> dataProvider;
- (NSString *)run;
@end
默认情况下,使用标准输入文件句柄:
@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
在您的测试中创建 TestDataProvider
:
@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
并在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
我有需要用户输入的方法
@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
那么,如何在测试用例函数中模拟用户的输入呢?
您有多种选择来实现这一点。下面两个很明显。
更改 run
以接受参数
- (void)run
到- (void)runWithFileHandle:(NSFileHandle *)handle
- 您的应用代码可以传递标准输入文件句柄
- 您的测试代码可以将句柄传递给具有所需输入的文件
用协议模拟它
创建 DataProvider
协议:
@protocol DataProvider
@property(readonly, copy) NSData *availableData;
@end
使NSFileHandle
符合这个协议:
@interface NSFileHandle (AvailableDataProvider) <DataProvider>
@end
在 TeamFormation
上存储实现此协议的对象:
@interface TeamFormation : NSObject
@property (nonatomic, nonnull, strong) id<DataProvider> dataProvider;
- (NSString *)run;
@end
默认情况下,使用标准输入文件句柄:
@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
在您的测试中创建 TestDataProvider
:
@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
并在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