ios - 如何使用 OCMock 模拟服务

标签 ios objective-c unit-testing ocmock

我正在尝试编写一个单元测试来创建一个 checklistItem,其属性定义如下:

typedef NS_ENUM (NSUInteger, ChecklistStatus) { Pending, Completed };
@protocol IChecklistItem <NSObject>
@property (nonatomic, assign, readonly) NSInteger Id;
@property (nonatomic, copy, readonly) NSString *Description;
@property (nonatomic, assign, readonly)BOOL IsCompleted;
@property (nonatomic, assign, readwrite) ChecklistStatus Status;
@property (nonatomic, strong, readwrite) NSDate *CompletedDate;
@property (nonatomic, copy, readwrite) NSString *CompletedByUserId;
@property (nonatomic, assign, readonly) NSInteger RoleId;
@property (nonatomic, assign, readonly) NSInteger GroupId;
@property (nonatomic, strong, readonly) NSArray<IChecklistNote> *Notes;

现在我在 XCTest 的设置方法中有这个设置:

_service = [[ChecklistService alloc]initWithUrl:[NSURL URLWithString:kcChecklistUrl] credentialsManager:self.credentialsManager];

这是我的单元测试的其余部分:

- (void)testCreateChecklistItem {
    XCTAssertNotNil(_service);
    CCChecklistItem *checklistItem = [CCChecklistItem new];
    CCChecklistItem *newChecklistItem = [CCChecklistItem new];
    newChecklistItem.Id = 2;
    newChecklistItem.Description = @"This is the Description";
    newChecklistItem.RoleId = 2;
    newChecklistItem.GroupId = 3;
    newChecklistItem.Notes = nil;
    newChecklistItem.Status = Completed;

    XCTestExpectation *checklistItemExpectation = [self expectationWithDescription:@"checklistItem"];

    id delegate = OCMProtocolMock(@protocol(ChecklistServiceDelegate));
    id mock = [OCMockObject mockForProtocol:(@protocol(IChecklistService))];
    [[[mock stub] andReturn:newChecklistItem] createChecklistItem:checklistItem delegate:delegate];

    OCMExpect(([delegate didCompleteCreateChecklistItem:[OCMArg checkWithBlock:^BOOL(id obj) {
        CCChecklistItem *items = obj;
        XCTAssertNotNil(items);
        double checklistId = items.Id;
        XCTAssert(checklistId != 0);
        [checklistItemExpectation fulfill];
    }]]));

    [_service createChecklistItem:checklistItem delegate:delegate];
    [self waitForExpectationsWithTimeout:5 handler:^(NSError *error) {
        if(error) {
        }
        OCMVerifyAll(delegate);
    }];
}

但是,我收到错误 failed: caught "NSUnknownKeyException", "[<__NSCFString 0x7faeaad6bd60> valueForUndefinedKey:]: this class is not key value coding-compliant for the key CompletedBy."

createChecklistItem 定义如下:

- (void)createChecklistItem:(id<IChecklistItem>)checklistItem delegate:(NSObject<ChecklistServiceDelegate> *)delegate
{
    NSMutableArray *mockChecklistItem = [NSMutableArray new];
    [TestObjectLoader loadObject:mockChecklistItem
                    fromJSONFile:@"ChecklistItem"
                     withMapping:[MappingProvider checklistCreateMapping]];
    if (delegate != nil && [delegate respondsToSelector:@selector (didCompleteCreateChecklistItem:)]) {
        [delegate didCompleteCreateChecklistItem:(NSObject<IChecklistItem> *)mockChecklistItem];
    }
}

Checklist.json 在哪里

{
    "Id": 13,
    "Desc": "Checklist Description",
    "IsCompleted": "false",
    "TypeId": 1,
    "RoleId": 1,
    "Status": "C",
    "CompletedDateTime": "2015-06-23T00:00:00+00:00",
    "CompletedBy": "AC",
    "Notes": [
              {
              "Note": "test",
              "CreatedBy": "AC",
              "CreatedDateTime": "2015-06-23T00:00:00+00:00"
              }
              ]
}

基本上,我想模拟服务以及何时createChecklistItem被调用时,我只是想在对象上设置一个随机 Id 并将其传回,而不是通过 Json 文件中的 ChecklistService 读取它。反正有这样做吗?我在我的测试中加入了模拟,但我不相信我使用正确......

最佳答案

您实际上不需要 Checklist.json,您应该只返回一个具有不同 Id 的值。

所以...

- (void)createChecklistItem:(id<IChecklistItem>)checklistItem delegate:(NSObject<ChecklistServiceDelegate> *)delegate
{
    NSMutableArray *mockChecklistItem = [NSMutableArray new];
    [TestObjectLoader loadObject:mockChecklistItem
                    fromJSONFile:@"ChecklistItem"
                     withMapping:[MappingProvider checklistCreateMapping]];
    if (delegate != nil && [delegate respondsToSelector:@selector (didCompleteCreateChecklistItem:)]) {
        [delegate didCompleteCreateChecklistItem:(NSObject<IChecklistItem> *)mockChecklistItem];
    }
}

应该只是

checklistItem.Id = 2; //Random number

关于ios - 如何使用 OCMock 模拟服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31948588/

相关文章:

ios - 将用户定义的变量分配给 info.plist bool

objective-c - 如何在 Xcode 中自动创建 sqlite 数据库并将其放入应用程序包中

c++ - UnitTest++ 命令行参数

javascript - 如何使用 axios/jest 测试失败的请求

c# - 尝试使用 webgrid 对 Controller 进行单元测试时,HttpContext 为空

iphone - 如何将 NSCache 与通用 NSDiscardableContent 实现一起使用

css - focus-within 适用于 Android 浏览器,但不适用于 iOS

ios - 送奶工的推送并且无法在 iOS10 上运行

ios - 有什么简单的方法可以在 objective-c 中用一位数舍入 float 吗?

ios - CoreBluetooth XPC 连接在关闭 View Controller 时无效