Mocking and Spying

Harness provides comprehensive mocking and spying capabilities through Vitest's @vitest/spy package. The API is 100% compatible with Vitest's spy and mock functionality.

Creating Mock Functions

fn()

Create a mock function that tracks calls, arguments, and return values.

import { describe, test, expect, fn } from 'react-native-harness'

describe('mock functions', () => {
  test('basic mock function', () => {
    const mockFn = fn()
    
    mockFn('arg1', 'arg2')
    mockFn('arg3')
    
    expect(mockFn).toHaveBeenCalledTimes(2)
    expect(mockFn).toHaveBeenCalledWith('arg1', 'arg2')
    expect(mockFn).toHaveBeenLastCalledWith('arg3')
  })

  test('mock with implementation', () => {
    const mockFn = fn((x: number, y: number) => x + y)
    
    const result = mockFn(2, 3)
    
    expect(result).toBe(5)
    expect(mockFn).toHaveBeenCalledWith(2, 3)
  })

  test('mock return values', () => {
    const mockFn = fn()
    
    mockFn.mockReturnValue('mocked')
    expect(mockFn()).toBe('mocked')
    
    mockFn.mockReturnValueOnce('once').mockReturnValue('default')
    expect(mockFn()).toBe('once')
    expect(mockFn()).toBe('default')
  })
})

Spying on Existing Methods

spyOn()

Create a spy that watches calls to an existing method while preserving the original implementation.

import { describe, test, expect, spyOn } from 'react-native-harness'

describe('spying', () => {
  test('spy on object method', () => {
    const calculator = {
      add: (a: number, b: number) => a + b
    }
    
    const spy = spyOn(calculator, 'add')
    
    const result = calculator.add(2, 3)
    
    expect(result).toBe(5) // Original implementation still works
    expect(spy).toHaveBeenCalledWith(2, 3)
    expect(spy).toHaveReturnedWith(5)
  })

  test('spy with mock implementation', () => {
    const obj = {
      method: (x: number) => x * 2
    }
    
    const spy = spyOn(obj, 'method').mockImplementation((x: number) => x * 3)
    
    expect(obj.method(4)).toBe(12) // Uses mocked implementation
    expect(spy).toHaveBeenCalledWith(4)
    
    spy.mockRestore() // Restore original implementation
    expect(obj.method(4)).toBe(8) // Back to original
  })
})

Mock Management

clearAllMocks()

Clear call history for all mocks while keeping their implementations.

import { describe, test, expect, fn, clearAllMocks, afterEach } from 'react-native-harness'

describe('mock management', () => {
  afterEach(() => {
    clearAllMocks()
  })

  test('clear all mocks', () => {
    const mock1 = fn()
    const mock2 = fn()
    
    mock1('test')
    mock2('test')
    
    expect(mock1).toHaveBeenCalledTimes(1)
    expect(mock2).toHaveBeenCalledTimes(1)
    
    clearAllMocks()
    
    expect(mock1).toHaveBeenCalledTimes(0)
    expect(mock2).toHaveBeenCalledTimes(0)
    // But implementations are preserved
    expect(typeof mock1).toBe('function')
    expect(typeof mock2).toBe('function')
  })
})

resetAllMocks()

Reset all mocks to their initial state, clearing both call history and implementations.

import { test, expect, fn, resetAllMocks } from 'react-native-harness'

test('reset all mocks', () => {
  const mockFn = fn().mockReturnValue('mocked')
  
  expect(mockFn()).toBe('mocked')
  
  resetAllMocks()
  
  expect(mockFn()).toBeUndefined() // Implementation reset
  expect(mockFn).toHaveBeenCalledTimes(0) // Call history cleared
})

restoreAllMocks()

Restore all spied methods to their original implementations.

import { test, expect, spyOn, restoreAllMocks } from 'react-native-harness'

test('restore all mocks', () => {
  const obj = {
    method: () => 'original'
  }
  
  const spy = spyOn(obj, 'method').mockReturnValue('mocked')
  
  expect(obj.method()).toBe('mocked')
  
  restoreAllMocks()
  
  expect(obj.method()).toBe('original') // Back to original implementation
})

Spy Assertions

Harness supports all Vitest spy assertions:

import { test, expect, fn } from 'react-native-harness'

test('spy assertions', () => {
  const spy = fn()
  
  spy('arg1', 'arg2')
  spy('arg3')
  
  // Call verification
  expect(spy).toHaveBeenCalled()
  expect(spy).toHaveBeenCalledTimes(2)
  expect(spy).toHaveBeenCalledWith('arg1', 'arg2')
  expect(spy).toHaveBeenLastCalledWith('arg3')
  expect(spy).toHaveBeenNthCalledWith(1, 'arg1', 'arg2')
  
  // Return value verification (for functions that return values)
  const returningFn = fn().mockReturnValue('result')
  returningFn()
  
  expect(returningFn).toHaveReturnedWith('result')
  expect(returningFn).toHaveReturnedTimes(1)
})

Complete API Reference

Harness provides the complete Vitest spy and mock API including:

  • Mock Functions: fn(), mock implementations, return values
  • Spying: spyOn(), method restoration
  • Mock Management: clearAllMocks(), resetAllMocks(), restoreAllMocks()
  • Spy Assertions: All toHaveBeenCalled* and toHaveReturned* matchers

For module mocking capabilities, see the Module Mocking documentation.

Need React or React Native expertise you can count on?

Need to boost your app's performance?
We help React Native teams enhance speed, responsiveness, and efficiency.