skills/setup-mocks/SKILL.md
Add the UI_TESTING / .mock services pattern to the app entry point so Grantiva can run tests with deterministic data and no live server. Use before make-tests when the app talks to an API.
npx skillsauth add grantiva/swift-assist setup-mocksInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Add closure-based mock services to the app entry point behind a #if UI_TESTING compilation flag, and configure grantiva.yml to build with that flag active. This gives Grantiva a fully deterministic app - no running server, no flaky network calls, no authentication required.
/swift-assist:setup-mocks
/swift-assist:setup-mocks --entry=Sources/MyApp/MyApp.swift
--entry=<file>: Path to the app entry point file containing @main (auto-detected if omitted)Tests that hit a real server are slow, flaky, and require credentials. When you build with UI_TESTING, the app swaps every live service for an in-memory mock that returns canned data instantly. Every test run sees the exact same state, which means screenshot baselines are stable and CI never fails because the staging environment is down.
The pattern uses closure-based dependency injection - no protocols, no generics. Live services capture real API clients. Mock services return hardcoded fixtures from a local store.
grantiva.yml must exist (run /swift-assist:init first)@main struct) must be identifiedIf --entry is not specified, search for the file with @main:
grep -rl "@main" --include="*.swift" .
Read the file and identify:
init() or as stored properties)DataService, AuthService, ImageService).environmentObject(), direct init args, etc.)For each service, read its definition to understand:
var fetchLandmarks: () async throws -> [Landmark]).live static var already exists.mock or .preview static var already existsIf .mock variants already exist for all services, tell the user and skip to Phase 5 (just update grantiva.yml).
For each service that lacks a .mock variant, generate one. The mock uses an in-memory store and returns data immediately without any async work:
// In DataService.swift (or a new DataService+Mock.swift file)
extension DataService {
static let mock: Self = {
var landmarks = Landmark.previewData // use existing preview data if available
return DataService(
fetchLandmarks: {
return landmarks
},
fetchLandmark: { id in
guard let landmark = landmarks.first(where: { $0.id == id }) else {
throw DataServiceError.notFound
}
return landmark
},
updateLandmark: { updated in
if let index = landmarks.firstIndex(where: { $0.id == updated.id }) {
landmarks[index] = updated
}
}
)
}()
}
Key rules for mock implementations:
Landmark.previewData or similar if the app already has preview fixturesURLSession, CoreData, or any external dependency--error-casesIn the app entry point, wrap the service initialization in a conditional:
Before:
@main
struct LandmarksApp: App {
let dataService = DataService.live
let authService = AuthService.live
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(dataService)
.environmentObject(authService)
}
}
}
After:
@main
struct LandmarksApp: App {
#if UI_TESTING
let dataService = DataService.mock
let authService = AuthService.mock
#else
let dataService = DataService.live
let authService = AuthService.live
#endif
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(dataService)
.environmentObject(authService)
}
}
}
If services are initialized in a method or computed property rather than stored properties, adapt the pattern to fit the actual structure - do not force it into stored properties.
Add build_settings to activate the UI_TESTING flag at build time:
cat grantiva.yml
If build_settings already exists, add to it. If not, add a new section:
build_settings:
SWIFT_ACTIVE_COMPILATION_CONDITIONS: DEBUG UI_TESTING
This tells grantiva build to pass -DDEBUG -DUI_TESTING to the Swift compiler, activating the #if UI_TESTING blocks.
The full updated grantiva.yml should look something like:
scheme: Landmarks
simulator: iPhone 16 Pro
bundle_id: com.example.landmarks
build_settings:
SWIFT_ACTIVE_COMPILATION_CONDITIONS: DEBUG UI_TESTING
screens:
- name: Landmarks
path: launch
After making changes, rebuild to confirm the mock build compiles:
grantiva build
If the build fails, show the full error output and stop. Common issues:
PreviewData.swift file)Mock services configured.
Entry point: Sources/Landmarks/LandmarksApp.swift
Services mocked:
DataService -> DataService.mock (in-memory store, 5 landmarks)
AuthService -> AuthService.mock (always authenticated as "Test User")
grantiva.yml updated:
build_settings:
SWIFT_ACTIVE_COMPILATION_CONDITIONS: DEBUG UI_TESTING
Build succeeded with mock services active.
Next steps:
/swift-assist:make-tests - Generate flows (app now has stable test data)
/swift-assist:test - Run flows against the mock build
.mock or .preview variants already exist, reuse them - do not create duplicatesUI_TESTING to the non-mock build path - it must only apply inside #if UI_TESTINGtesting
Run visual regression testing using Grantiva's diff pipeline. Capture screenshots, compare against baselines, and report visual differences. Use for catching unintended UI changes.
testing
Approve current VRT captures as new baselines. Can approve all or specific screens selectively. Use after reviewing /swift-assist:vrt results.
testing
Run generated test flows against the app in the simulator using Grantiva. Use after /swift-assist:make-tests to execute and validate your user flows.
testing
Generate a GitHub Actions workflow that runs Grantiva VRT in CI on every pull request. Use to add cloud visual regression testing with GitHub Check integration to your project.