Внедрите трекер через протокол и проверьте его вызовы с помощью spy. Тестировать console output или настоящий singleton для этого не нужно.
Создай unit‑тесты для аналитического модуля
Внедрите трекер через протокол и проверьте его вызовы с помощью spy. Тестировать console output или настоящий singleton для этого не нужно.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Разработайте набор unit‑тестов для класса AppAnalytics. При желании можно расширять класс EventTracker.
final class EventTracker {
private init() {}
static let shared = EventTracker()
func track(event: String) {
print("Event \(event)")
}
}
/// -----
final class AppAnalytics {
func trackScreen() {
EventTracker.shared.track(event: "Screen")
}
}
Ответ
Внедрите трекер через протокол и проверьте его вызовы с помощью spy. Тестировать console output или настоящий singleton для этого не нужно.
protocol Tracking { func track(event: String) }
extension EventTracker: Tracking {}
final class AppAnalytics {
private let tracker: any Tracking
init(tracker: any Tracking = EventTracker.shared) {
self.tracker = tracker
}
func trackScreen() { tracker.track(event: "Screen") }
}
final class TrackerSpy: Tracking {
var events: [String] = []
func track(event: String) { events.append(event) }
}
final class AppAnalyticsTests: XCTestCase {
func testTrackScreenSendsExactlyOneScreenEvent() {
let spy = TrackerSpy()
let analytics = AppAnalytics(tracker: spy)
XCTAssertTrue(spy.events.isEmpty)
analytics.trackScreen()
XCTAssertEqual(spy.events, ["Screen"])
}
func testRepeatedCallsAreNotLost() {
let spy = TrackerSpy()
let analytics = AppAnalytics(tracker: spy)
analytics.trackScreen()
analytics.trackScreen()
XCTAssertEqual(spy.events, ["Screen", "Screen"])
}
}
Нужны import XCTest и импорт тестируемого модуля. У каждого теста свой spy, поэтому они не зависят от состояния singleton или порядка запуска.