Skip to main content

πŸ§ͺ Mock Services

Shipnative features a powerful mock services architecture that allows you to develop your entire frontend without needing to set up any backend services or API keys. This enables rapid prototyping, offline development, and a truly frontend-first workflow.

How it Works

Mock services automatically activate when the corresponding API keys are missing from your apps/app/.env file during development (__DEV__ environment). This means you can write code as if the real backend services are connected, and Shipnative will seamlessly swap in the mock implementations.

Automatic Detection Example

// apps/app/app/services/mocks/index.ts (simplified)
export const USE_MOCK_SUPABASE = __DEV__ && !process.env.EXPO_PUBLIC_SUPABASE_URL
export const USE_MOCK_POSTHOG = __DEV__ && !process.env.EXPO_PUBLIC_POSTHOG_API_KEY
// ... and so on for other services
When you add your real API keys to .env and restart your app, the mock services will automatically deactivate, and your app will connect to the live services – no code changes required!

Benefits of Mock Mode

  • Frontend-First Development: Start building your UI and user experience immediately, without waiting for backend setup or API key configuration.
  • Rapid Prototyping: Quickly iterate on features and designs without external dependencies.
  • Offline Development: Work on your app even without an internet connection.
  • Simplified Testing: Easily test various scenarios (e.g., different subscription states, empty data sets) by manipulating mock data.
  • Reduced Costs: Avoid incurring costs from third-party services during early development.

Available Mock Services

Shipnative provides comprehensive mock implementations for all its core services:
ServiceMock LocationReal ServicePurpose
Supabaseservices/mocks/supabase.ts@supabase/supabase-jsAuthentication, Database, Storage, Realtime, RPC
PostHogservices/mocks/posthog.tsposthog-react-nativeAnalytics, Feature Flags
Sentryservices/mocks/sentry.ts@sentry/react-nativeError Tracking
RevenueCatservices/mocks/revenueCat.tsreact-native-purchasesPayments (iOS, Android, Web)

Mock Service Capabilities

1. Supabase Mock

The Supabase mock (services/mocks/supabase.ts) provides a near-complete simulation of the real Supabase client.
  • Authentication:
    • βœ… Sign up, sign in, sign out with email/password.
    • βœ… Session management (persists in SecureStore).
    • βœ… Password reset (simulated).
    • βœ… User updates and auth state listeners.
    • βœ… OAuth (Google, Apple, GitHub, Twitter) flow simulation.
  • Database:
    • βœ… Full CRUD operations (Create, Read, Update, Delete).
    • βœ… All standard query filters (eq, neq, gt, gte, lt, lte, like, ilike, in).
    • βœ… Ordering, limiting, and pagination (order, limit, range).
    • βœ… Single row queries (single(), maybeSingle()).
    • βœ… Upsert operations.
    • βœ… In-memory storage with optional SecureStore persistence.
  • Storage:
    • βœ… File upload (upload()), download (download()), and removal (remove()).
    • βœ… List files (list()).
    • βœ… Public URLs (getPublicUrl()) and signed URLs (createSignedUrl()).
    • βœ… Bucket management.
  • Realtime:
    • βœ… Channel subscriptions.
    • βœ… Postgres changes (INSERT, UPDATE, DELETE) simulation.
    • βœ… Programmatic event triggering for testing.
  • RPC (Remote Procedure Call):
    • βœ… Register custom RPC handlers to simulate stored procedures.
Example Usage (same code for mock or real Supabase):
import { supabase } from '@/services/supabase'
// Authentication
const { error: signInError } = await supabase.auth.signInWithPassword({ email: 'test@example.com', password: 'password' })

// Database Query
const { data: posts, error: postsError } = await supabase
  .from('posts')
  .select('*')
  .eq('author_id', 'some-user-id')
  .order('created_at', { ascending: false })
  .limit(10)

// Storage Upload
const fileBlob = new Blob(['hello world'], { type: 'text/plain' });
const { data: uploadData, error: uploadError } = await supabase.storage
  .from('avatars')
  .upload('my-file.txt', fileBlob, { contentType: 'text/plain' })

2. PostHog Mock

The PostHog mock (services/mocks/posthog.ts) simulates analytics and feature flag functionality.
  • Analytics: Event tracking, screen tracking, user identification, user properties, groups.
  • Feature Flags: Simulated feature flag checks (isFeatureEnabled, getFeatureFlag).
  • Opt-in/Opt-out: Simulated behavior.

3. Sentry Mock

The Sentry mock (services/mocks/sentry.ts) captures and logs errors and performance data to the console.
  • Error Tracking: Exception capturing, message logging, breadcrumbs, user context, tags, and extra data.
  • Performance Monitoring: Simulated performance transaction logging.

4. RevenueCat Mock

The RevenueCat mock (services/mocks/revenueCat.ts) simulates in-app purchase flows.
  • Subscriptions: Purchase flow (always succeeds), restore purchases, get offerings/packages, customer info, entitlements, subscription states.

Testing Utilities

Each mock service provides helper utilities for testing specific scenarios, such as seeding data, triggering events, or simulating errors.

Supabase Mock Testing Utilities

import { mockSupabaseHelpers } from '@/services/mocks/supabase'
// Seed database tables with test data
mockSupabaseHelpers.seedTable('posts', [
  { id: 1, title: 'Welcome Post', content: 'This is a test post', author_id: 'mock-user-123' },
])
mockSupabaseHelpers.seedTable('profiles', [
  { id: 'mock-user-123', email: 'test@example.com', first_name: 'Test', last_name: 'User' },
])

// Get current data from a mock table
const posts = mockSupabaseHelpers.getTableData('posts')

// Clear all mock data
mockSupabaseHelpers.clearAll()

// Simulate an error for a specific Supabase method
mockSupabaseHelpers.simulateError('database', 'posts.select', new Error('Network unavailable'))

// Trigger a realtime event for testing subscriptions
mockSupabaseHelpers.triggerRealtimeEvent('posts', 'INSERT', { id: 3, title: 'New Realtime Post' })

RevenueCat Mock Testing Utilities

import { mockRevenueCat } from '@/services/mocks/revenueCat'
// Simulate a user having 'pro' status
mockRevenueCat.setProStatus(true)

// Check current 'pro' status
const isPro = mockRevenueCat.getIsPro()

// Reset mock RevenueCat state
mockRevenueCat.reset()

Mock Service Behavior Details

Data Persistence

  • During App Session: Mock data persists in memory throughout the app’s current session. Authentication sessions are maintained, and database queries work across components.
  • On App Restart: All mock data is cleared, and the user is logged out. Database tables will be empty.
    • Solution for Testing: Use mockSupabaseHelpers.seedTable() in your app’s initialization logic or test setup to re-populate data.

Network Delays

Mock services simulate realistic network delays to help you test loading states and user experience.

Console Logging

All mock operations log detailed information to the console, which is invaluable for debugging and understanding data flow.
πŸ” [MockSupabase] Sign in: user@example.com
πŸ’Ύ [MockSupabase] SELECT * FROM posts
πŸ“Š [MockPostHog] Event: button_clicked
πŸ› [MockSentry] Exception: Error message
πŸ’° [MockRevenueCat] Purchase: pro_monthly

Transitioning to Production

When you’re ready to use real services, simply add your API keys to your apps/app/.env file and restart your app. The mock services will automatically deactivate, and your application will connect to the live backend services. No code changes are needed!
# Example .env with real API keys
EXPO_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
EXPO_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
EXPO_PUBLIC_POSTHOG_API_KEY=your-posthog-key
EXPO_PUBLIC_SENTRY_DSN=your-sentry-dsn
EXPO_PUBLIC_REVENUECAT_IOS_KEY=your-rc-ios-key
# ... etc.

Limitations

While mock services are powerful, some advanced features of real services cannot be fully replicated:
  • Row Level Security (RLS): Mock Supabase does not enforce RLS policies.
  • Advanced Database Features: Complex database functions, triggers, or highly specific filters might not be fully supported.
  • Performance Testing: Mocks do not accurately reflect the performance characteristics of real backend services.
For these scenarios, you will need to test with real backend services.