سؤال

I'm adding some unit tests to a project and want to have a test that checks that the array returned from a method is immutable so I created the following unit test:

- (void)testReturnedObjectIsOfTypeImmutableArray
{
    XCTAssertEqualObjects([NSArray class],
                          [[NSArray reverseArray:self.array] class],
                          @"NSArray should be returned");
}

However this fails because the object being returned is of class "__NSArrayI" instead of "NSArray".

I can't work out how to adapt the above to have "_NSArrayI" be acceptable where as receiving "_NSArrayM" or "NSMutableArray" should be unacceptable.

هل كانت مفيدة؟

المحلول

As suggested in the answer to How to get classname in objective c Like 'NSString', you could use classForCoder instead of class. Example:

NSArray *a = @[@"foo"];
NSMutableArray *b = [a mutableCopy];

NSLog(@"a class: %@", [a class]); // -> __NSArrayI
NSLog(@"b class: %@", [b class]); // -> __NSArrayM
NSLog(@"a classForCoder: %@", [a classForCoder]); // -> NSArray
NSLog(@"b classForCoder: %@", [b classForCoder]); // -> NSMutableArray

So this test should give the expected results:

- (void)testReturnedObjectIsOfTypeImmutableArray
{
    XCTAssertEqualObjects([NSArray class],
                          [[NSArray reverseArray:self.array] classForCoder],
                          @"NSArray should be returned");
}

نصائح أخرى

Testing for class equality is a problem with class clusters.

Use isKindOfClass:[NSArray class] to check whether the object is a subclass of NSArray and then check if it responds to selector @selector(addObject:) to see if it's mutable.

BOOL isArray = [self.array isKindOfClass:[NSArray class]];
BOOL isMutable = [self.array respondsToSelector:@selector(addObject:)];
XCTAssertTrue(isArray && !isMutable, @"...");

_NSArrayI is an NSArray, so if your reverseArray is returning a NSArray, it should work.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top