An open API service indexing awesome lists of open source software.

https://github.com/easypackages/easymock

🎭 Lightweight Swift mocking library with async/await, delays, and error simulation
https://github.com/easypackages/easymock

easypackages mock spm stub swift testing

Last synced: about 1 year ago
JSON representation

🎭 Lightweight Swift mocking library with async/await, delays, and error simulation

Awesome Lists containing this project

README

          

![Banner](./doc-images/banner.jpg)

[![Swift](https://github.com/EasyPackages/EasyMock/actions/workflows/swift.yml/badge.svg)](https://github.com/EasyPackages/EasyMock/actions/workflows/swift.yml)

# Simulate. Test. Verify

A lightweight and expressive library for unit testing in Swift β€” supporting `async/await`, delays, error simulation, and call tracking.

## Overview

**EasyMock** is a test utility designed for creating mock objects (test doubles) in Swift with minimal setup and maximum readability.

It’s ideal for testing interactions, async flows, and error handling β€” without boilerplate.

### ✨ Features

- βœ… Controlled input/output (stubbing)
- πŸ” Call tracking (spies)
- ⏱ Simulated delays (like network latency)
- πŸŒ€ Full `async/await` support
- ❗ Error simulation (`throw`)
- πŸ§ͺ Designed for clarity in unit tests

## Why Use EasyMock?

### Replace This:

```swift
final class AuthenticatorMock: Authenticator {
private(set) var authenticateCallCount = 0
private(set) var wasCalledWithCredential: Credential?
var credentialDelay: Double?
var authenticateStub = makeAnyAuthenticated()
var authenticateErrorStub: Error?

func authenticate(_ credential: Credential) async throws -> Authenticated {
if let delay {
try await Task.sleep(nanoseconds: UInt64(delay * 1_000_000_000))
}

if let authenticateErrorStub {
throw authenticateErrorStub
}

authenticateCallCount += 1
wasCalledWithCredential = credential
return authenticateStub
}
}
```

### With This:

```swift
struct AuthenticatorMock: Authenticator {
let authenticateMocked = AsyncThrowableMock(makeAnyAuthenticated())

func authenticate(_ credential: Credential) async throws -> Authenticated {
try await authenticateMocked.synchronize(credential)
}
}
```

## Installation

### Using Swift Package Manager

Simply add a package to your project passing in https://github.com/EasyPackages/EasySymbol.

In your dependency you can add this in your Package.swift:

```swift
dependencies: [
.package(
url: "https://github.com/EasyPackages/EasyMock.git",
from: "1.0.0"
)
]
```

In your target:

```swift
.target(
name: "YourApp",
dependencies: ["EasyMock"]
)
```

## Examples

### Basic Mock

```swift
let mock = Mock(true)
let result = mock.synchronize("input")

#expect(mock.spies == ["input"])
#expect(result == true)
```

### AsyncMock

```swift
let asyncMock = AsyncMock("Done")
asyncMock.mock(delay: 1.0)

let result = await asyncMock.synchronize()
#expect(result == "Done")
```

### ThrowableMock

```swift
enum LoginError: Error { case invalid }

let mock = ThrowableMock(false)
mock.mock(throwing: LoginError.invalid)

XCTAssertThrowsError(try mock.synchronize("admin"))
```

### AsyncThrowableMock

```swift
let asyncMock = AsyncThrowableMock(42)
asyncMock.mock(delay: 0.5)
asyncMock.mock(throwing: nil)

let value = try await asyncMock.synchronize("ping")
XCTAssertEqual(value, 42)
```

## Supported Platforms

- iOS 13+
- macOS 10.15+
- Swift 5.9+

## Author

Created by [Paolo Prodossimo Lopes](https://github.com/PaoloProdossimoLopes)
Feel free to contribute, open issues, or suggest improvements.