Почему передача объекта NSString в параметр "format" XCTAssertTrue вызывает ошибку сборки?
При попытке использовать XCTest для тестирования моего приложения, я получаю ошибку сборки при выполнении следующих действий:
#import <XCTest/XCTest.h>
@interface MyTests : XCTestCase
@end
@implementation MyTests
- (void)testExample
{
NSString *str = @"foo";
XCTAssertTrue(YES, str); // Parse issue: Expected ')'
}
@end
но я не получаю ошибку сборки, если я это делаю:
#import <XCTest/XCTest.h>
@interface MyTests : XCTestCase
@end
@implementation MyTests
- (void)testExample
{
XCTAssertTrue(YES, @"foo"); // this is just fine...
}
@end
Ошибка сборки, которую я получаю:
Parse issue: Expected ')'
и он помещает стрелку под "s" в "str".
Я обнаружил, что могу исправить это, изменив
XCTAssertTrue(YES, str)
к
XCTAssertTrue(YES, @"%@", str)
но я просто не могу понять, почему это имеет значение. Может кто-нибудь объяснить, почему это так?
Ответы
Ответ 1
Макросы XCT...
записываются для принятия форматированных строк - сами строки необязательны (так что запись XCTAssertTrue(YES)
действительна), но они должны быть постоянными строками. Вы не можете передавать объекты в макрос без строки формата, поэтому XCTAssertTrue(YES, @"%@", str)
работает, но, скажем, XCTAssertTrue(YES, str)
или XCTAssertTrue(NO, nil)
не будет.
Ответ 2
Глубоко внутри реализации код выполняет следующее:
@"" format
Если format
является константным строковым литералом, компилятор объединяет строки. Если format
- это что-то еще, вы получаете ошибку компилятора.
Ответ 3
Передача предварительно определенного текста в утверждение иногда желательно так:
XCTAssertTrue(YES, @"foo"); // this is just fine...
Как и этот
#define FOO @"foo"
XCTAssertTrue(YES, FOO); // this is just fine too...
Итак, я делаю такие вещи, как:
#define DBUEqualityTestFailed @"Equality test failed"
// test
DBNumber *n1 = [@((int)1) dbNumberFromIntValue];
XCTAssertTrue(*(int *)[n1 valuePointer] == 1, DBUEqualityTestFailed);
XCTAssertTrue([n1 valuePointer] == [n1 valuePointer], DBUEqualityTestFailed);
XCTAssertTrue(*(int *)[n1 valuePointer] == *(int *)[n1 valuePointer], DBUEqualityTestFailed);