У меня есть следующий тестовый класс, который получает данные с удаленного сервера и пытается проверить их на ноль:
import XCTest
@testable import DogYears
class DogYearsUnitTests: XCTestCase {
var resData: Data? = nil
func testInfoLoading(){
let url = "https://raw.githubusercontent.com/FahimF/Test/master/DogYears-Info.rtf"
HTTPClient.shared.get(url: url) { (data, error) in
XCTAssertNil(error)
XCTAssertNotNil(data)
self.resData = data
}
let predicate = NSPredicate(format: "resData != nil")
let exp = expectation(for: predicate, evaluatedWith: self, handler: nil)
let res = XCTWaiter.wait(for: [exp], timeout: 5.0)
if res == XCTWaiter.Result.completed {
XCTAssertNotNil(resData, "No data recieved from server for InfoView content")
} else {
XCTAssert(false)
}
}
}
Это работает, но мне интересно, почему NSPredicate не работает. Видите ли, замена let predicate = NSPredicate(format: "resData != nil") на let predicate = NSPredicate(format: "resData == nil") не дает никакого эффекта, и тест все равно пройден, почему он пройден даже для этого let predicate = NSPredicate(format: "resData == nil") ?
@matt это вообще не связано с вопросом
Да это так. Речь идет о порядке выполнения кода. — Также вы должны имитировать/заглушать сетевые вызовы; нет необходимости тестировать реальную сеть, мы знаем, что она делает.
@matt var устанавливается в закрытии после задержки, но предикат должен оцениваться после установленного мной временного интервала.
Вы просто бросаете кости. Вам нужно создать ожидание до, когда вы начнете работать в сети, а выполнить — это внутри асинхронного блока. Читать developer.apple.com/documentation/xctest/….
@matt Я могу предположить, что блок, когда я устанавливаю ожидание, выполняется до завершения работы сети (потому что это асинхронная операция).





Тест пройден с let predicate = NSPredicate(format: "resData == nil"), потому что это верно при запуске, так как запрос не выполняется одновременно) И ваш таймер вам не помогает. А также передается с таймером let predicate = NSPredicate(format: "resData != nil") должного, ваш запрос успевает получить данные.
Вот простой пример: https://developer.apple.com/documentation/xctest/asynchronous_tests_and_expectations/testing_asynchronous_operations_with_expectations
Вы можете переписать свой тест так, где вместо вашего запроса я запускаю код в другом потоке, я думаю, что это легче читать:
class DogYearsUnitTests: XCTestCase {
var resData: Data? = nil
func testInfoLoading(){
let expectation = XCTestExpectation(description: "Download apple.com home page")
DispatchQueue.global().async {
Thread.sleep(forTimeInterval: 3)
self.resData = Data()
expectation.fulfill()
}
// Wait until the expectation is fulfilled, with a timeout of 10 seconds.
wait(for: [expectation], timeout: 10.0)
XCTAssertNotNil(resData)
}
}
отлично, как переписать его, чтобы оператор предиката повлиял на тестовый пример?
Я переписал его, надеюсь, это поможет вам