Доступ к свойству только для чтения при тестировании iOS Swift - PullRequest
0 голосов
/ 08 мая 2018

Я довольно новичок в iOS и Swift, и в настоящее время я сталкиваюсь с проблемой при написании модульного теста. У меня есть класс (предположим, он называется A), который имеет (свойство readonly из Objective-C), и в моем тесте я хочу, чтобы объект этого класса передавался методу, который позже что-то с ним делает. Ой, у меня тоже нет инициализаторов ... Мой вопрос, как проверить такое мышление? Может быть, я должен как-то издеваться над таким объектом?

------ EDIT -----

Хорошо. Мой пост был не совсем точным. Итак, я знаю только основы Swift (к сожалению, сейчас у меня нет времени изучать Objective-C, поскольку меня попросили написать sth на Swift). У меня есть класс, предоставленный какой-то компанией, в которой у меня есть класс (написанный на Objective-C), такой как:

@interface MainClassX : NSObject
    @property (nonatomic, strong, readonly) NSString* code;

   @property (nonatomic, strong, readonly) NSArray<XYZ*>* classification;

@end

И в моем тесте я хочу создать объект этого класса и инициализировать хотя бы свойство 'code' ... но установщик является частным, поэтому я не могу сделать какой-либо 'трюк наследования' ...? Есть ли вариант сделать это или я должен сделать это по-другому? Проблема в том, что я хочу протестировать метод, который принимает массив таких объектов и делает с ними что-то еще.

Ответы [ 2 ]

0 голосов
/ 09 мая 2018

Это довольно сложно, потому что они хотели, чтобы эти свойства были доступны только для чтения, зачем вам их проверять?

Независимо от цели, вы можете сделать эти шаги: 1. Посмотрите на добавление методов к этому классу, используя Category (в Objective C) или расширение (в Swift). 2. Внедрите этот новый метод инициализации, установите code свойство с помощью Программирование значения ключа

Мне удалось сделать это очень быстро в Objective C, довольно просто конвертировать в Swift.

@implementation MainClassX(Test)
-(instancetype)initWithCode:(NSString *)code {
    self = [self init];

    if (self) {
        [self setValue:code forKey:@"code"];
    }

    return self;
}
@end

Проверьте это:

MainClassX *test = [[MainClassX alloc] initWithCode:@"TEST"];

NSLog(@"code: %@", test.code); // Should print out "TEST" in the console

Swift:

extension MainClassX {
    convenience init(_ code: String) {
        self.init()
        self.setValue(code, forKey: "code")
    }
}

В модульном тесте:

import XCTest
@testable import YourAppModule


class YourAppModuleTests: XCTestCase {

    override func setUp() {
        super.setUp()
        // Put setup code here. This method is called before the invocation of each test method in the class.
    }

    override func tearDown() {
        // Put teardown code here. This method is called after the invocation of each test method in the class.
        super.tearDown()
    }

    func testExample() {
        // This is an example of a functional test case.
        // Use XCTAssert and related functions to verify your tests produce the correct results.
        let cls = MainClassX("TEST")
        XCTAssert(cls.code == "TEST")
    }

    func testPerformanceExample() {
        // This is an example of a performance test case.
        self.measure {
            // Put the code you want to measure the time of here.
        }
    }

}
0 голосов
/ 08 мая 2018

Вы, вероятно, ищете инъекцию зависимости. Это способ инициализации класса необязательным значением, которое может устанавливать значения для тестирования, как вы хотите.

Ниже приведен простой пример.

Создайте дополнительную инициализацию для вашего класса Objective C:

- (instancetype)initWithOption:(NSString *)option {
    self = [super init];

    if (self) {
        self.option = option;
    }

    return self;
}

У вас может быть такое, что когда вы обычно вызываете класс, вы вызываете init по умолчанию. Но для тестирования инициализируйте его с помощью этой функции. Еще одна вещь, которую стоит учесть, если вы захотите иметь защищенный заголовочный файл (например, classname_protected.h), который вы используете только в своих модульных тестах, чтобы вы не открывали эту функцию для своего приложения.

Не видя больше вашего теста, это немного сложно добавить к этому, но DI, вероятно, там, где вам нужно пойти на это.

...