分配给Readonly Property Objective-C

时间:2015-08-07 06:37:13

标签: objective-c

我正在编写单元测试来测试更新核对表的方法。清单具有以下属性:

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;

- (void)sortNotes;
@end

然而,在我的单元测试中,我正在尝试验证,

checklistItem.Description = @"hello";,我收到错误&#34;分配给readonly属性&#34;

为什么会这样?

继承我测试方法的其余部分:

- (void)testUpdateChecklist {
    NSString *testChecklistId = @"1";
    NSString *testPatientDescription = @"Descriptive Description";

    // What other properties do I need here?
    XCTAssertNotNil(_service);
    __block CCChecklistItem *checklistItem = nil;

    SignalBlocker *blocker = [[SignalBlocker alloc] initWithExpectedSignalCount:1];
    id delegate = OCMProtocolMock(@protocol(ChecklistServiceDelegate));
    OCMExpect([delegate didCompleteUpdateChecklistItem:[OCMArg checkWithBlock:^BOOL(id obj) {
        checklistItem = obj;
        XCTAssertNotNil(checklistItem);
        [blocker signal];
        return true;
    }]]);

    [_service updateChecklistItem:checklistItem delegate:delegate];
    [blocker waitWithTimeout:5.0f];
    OCMVerifyAll(delegate);

    NSString *originalDescription = checklistItem.Description;

    checklistItem.Description = @"hello";

}

编辑问题:

因此,当我将属性从上面更改为ReadWrite时,我在CChecklistItem中出现此错误

@interface CCChecklistItem ()
@property (nonatomic, assign, readwrite) NSInteger Id;
@property (nonatomic, copy, readwrite) NSString *Description;
@property (nonatomic, assign, readwrite) NSInteger RoleId;
@property (nonatomic, assign, readwrite) NSInteger GroupId;
@property (nonatomic, strong, readwrite) NSMutableArray<IChecklistNote> *Notes;
@end

`在类扩展中非法重新声明readwrite属性&#39; CChecklistItem&#39;

3 个答案:

答案 0 :(得分:1)

您的属性设置为readonly,如下所示:

@property (nonatomic, copy, readonly) NSString *Description;

将其更改为:

@property (nonatomic, copy) NSString *Description;

或者如果你想与其他属性保持一致(虽然过于明确,IMO):

@property (nonatomic, copy, readwrite) NSString *Description;

答案 1 :(得分:0)

不鼓励仅更改范围可见性以满足测试。在您的情况下,最简单的解决方案是利用Objective-C为您提供的精彩KVO

翻译成您原来的问题,它将类似于:

[checklistItem setValue:@"hello" forKey:@"Description"]

无需更改访问修饰符,您的测试也没问题。

答案 2 :(得分:0)

您的属性在类readonly符合的协议中声明为CChecklistItem。然后,当该属性被合成时,它将创建支持变量和getter方法-(NSString *)description;但不创建setter方法,因为它是readonly。因此,在您的匿名类别中将其重新声明为readwright,我猜测在您的测试文件中声明将私有方法公开给测试用例,因为该属性仍然没有setter方法,所以无法工作。此外,即使您决定尝试在类的实现中创建自己的setter,也不能,因为无法访问仅在{{1中公开的变量_description文件。

根据您需要对测试执行的操作,它可能适用于CChecklistItem.m getter stub并在调用该方法时返回您的- (NSString *)description;字符串,而不是尝试设置实际支持变量的值。