{"id":19826175,"url":"https://github.com/0xleif/mocked","last_synced_at":"2026-01-24T04:33:25.253Z","repository":{"id":260821605,"uuid":"882393811","full_name":"0xLeif/Mocked","owner":"0xLeif","description":"🛠️ Effortless Mock Generation for Swift Protocols","archived":false,"fork":false,"pushed_at":"2024-11-07T05:54:07.000Z","size":38,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-19T12:50:48.503Z","etag":null,"topics":["async","await","ios","macos","macros","mock","mocking","protocols","sendable","swift","testing","tvos","ubuntu","visionos","watchos","windows"],"latest_commit_sha":null,"homepage":"https://0xleif.github.io/Mocked/","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/0xLeif.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-11-02T18:01:53.000Z","updated_at":"2025-01-08T23:31:54.000Z","dependencies_parsed_at":"2024-11-02T20:23:53.933Z","dependency_job_id":"4dca4644-c293-456f-9c1e-503902bdefb1","html_url":"https://github.com/0xLeif/Mocked","commit_stats":null,"previous_names":["0xleif/mocked"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/0xLeif/Mocked","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0xLeif%2FMocked","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0xLeif%2FMocked/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0xLeif%2FMocked/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0xLeif%2FMocked/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/0xLeif","download_url":"https://codeload.github.com/0xLeif/Mocked/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0xLeif%2FMocked/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28711523,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-23T23:51:44.727Z","status":"online","status_checked_at":"2026-01-24T02:00:06.909Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["async","await","ios","macos","macros","mock","mocking","protocols","sendable","swift","testing","tvos","ubuntu","visionos","watchos","windows"],"created_at":"2024-11-12T11:09:41.804Z","updated_at":"2026-01-24T04:33:25.230Z","avatar_url":"https://github.com/0xLeif.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Mocked\n\n[![macOS Build](https://img.shields.io/github/actions/workflow/status/0xLeif/Mocked/macOS.yml?label=macOS\u0026branch=main)](https://github.com/0xLeif/Mocked/actions/workflows/macOS.yml)\n[![Ubuntu Build](https://img.shields.io/github/actions/workflow/status/0xLeif/Mocked/ubuntu.yml?label=Ubuntu\u0026branch=main)](https://github.com/0xLeif/Mocked/actions/workflows/ubuntu.yml)\n[![Windows Build](https://img.shields.io/github/actions/workflow/status/0xLeif/Mocked/windows.yml?label=Windows\u0026branch=main)](https://github.com/0xLeif/Mocked/actions/workflows/windows.yml)\n[![License](https://img.shields.io/github/license/0xLeif/Mocked)](https://github.com/0xLeif/Mocked/blob/main/LICENSE)\n[![Version](https://img.shields.io/github/v/release/0xLeif/Mocked)](https://github.com/0xLeif/Mocked/releases)\n\nMocked is a Swift 6 compiler macro that automatically generates mock implementations for protocols. This can be especially useful for unit testing, allowing you to easily create mock objects to verify behavior and interactions in your tests.\n\n## Features\n\n- **Automatic Mock Generation**: Simply annotate your protocol with `@Mocked`, and a mock implementation will be generated.\n- **Supports Properties and Methods**: Generates mock versions of properties and methods, including `async` and `throws` variants.\n- **Access Level Control**: You can specify the access level (`open`, `public`, `package`, `internal`, `fileprivate`, `private`) for the generated mock.\n- **Configurable Behavior**: Easily override behavior by providing closures during initialization of the mock.\n- **Support for Associated Types**: The `Mocked` macro handles protocols with associated types using generics.\n- **Automatic Detection of Class Requirements**: If the protocol conforms to `AnyObject`, a class is generated instead of a struct, maintaining reference semantics.\n\n## Installation\n\nTo use Mocked in your project, add it as a dependency using Swift Package Manager. Add the following to your `Package.swift` file:\n\n```swift\n.package(url: \"https://github.com/0xLeif/Mocked.git\", from: \"1.0.0\")\n```\n\nAnd add it as a dependency to your target:\n\n```swift\n.target(\n    name: \"YourTargetName\",\n    dependencies: [\n        \"Mocked\"\n    ]\n)\n```\n\n## Usage\n\nTo generate a mock for a protocol, simply annotate it with `@Mocked`:\n\n```swift\n@Mocked\nprotocol MyProtocol {\n    var title: String { get set }\n    func performAction() -\u003e Void\n}\n```\n\nThis will generate a mock struct named `MockedMyProtocol` that conforms to `MyProtocol`. You can use this mock in your unit tests to validate behavior.\n\n### Example\n\n```swift\n@Mocked\nprotocol MyProtocol {\n    var title: String { get set }\n    func performAction() -\u003e Void\n}\n\nlet mock = MockedMyProtocol(\n    title: \"Test Title\",\n    performAction: { print(\"Action performed\") }\n)\n\nmock.performAction()  // Output: \"Action performed\"\n```\n\n### Default Implementations\n\nIf a protocol has a default implementation provided in an extension, the generated mock will use this default implementation unless an override is specified.\n\n```swift\nprotocol DefaultProtocol {\n    func defaultMethod() -\u003e String\n}\n\nextension DefaultProtocol {\n    func defaultMethod() -\u003e String {\n        return \"default\"\n    }\n}\n\n@Mocked\nprotocol CustomProtocol: DefaultProtocol {\n    func customMethod() -\u003e Bool\n}\n\nlet mock = MockedCustomProtocol(\n    customMethod: { true }\n)\n\nprint(mock.defaultMethod())  // Output: \"default\"\n```\n\n### Advanced Usage\n\nThe `Mocked` macro can be used with more complex protocols, including those with associated types, `async` methods, `throws` methods, or a combination of both.\n\n```swift\n@Mocked\nprotocol ComplexProtocol {\n    associatedtype ItemType\n    associatedtype ItemValue: Codable\n    func fetchData() async throws -\u003e ItemType\n    func processData(input: Int) -\u003e Bool\n    func storeValue(value: ItemValue) -\u003e Void\n}\n\nlet mock = MockedComplexProtocol\u003cString, Int\u003e(\n    fetchData: { return \"Mocked Data\" },\n    processData: { input in return input \u003e 0 }\n)\n\n// Usage in a test\nTask {\n    do {\n        let data = try await mock.fetchData()\n        print(data)  // Output: \"Mocked Data\"\n    } catch {\n        XCTFail(\"Unexpected error: \\(error)\")\n    }\n}\n\nlet isValid = mock.processData(input: 5)\nXCTAssertTrue(isValid)\n```\n\n### Edge Cases and Warnings\n\n- **Non-Protocol Usage**: The `@Mocked` macro can only be applied to protocols. Using it on other types will result in a compilation error.\n- **Unimplemented Methods**: Any method that is not overridden will call `fatalError()` if invoked. Ensure all required methods are implemented when using the generated mock.\n- **Async and Throwing Methods**: The generated mocks handle `async` and `throws` methods appropriately, but be sure to provide closures that match the method signatures.\n\n## Limitations\n\n- **No Function-Level Generics**: Generics are supported only at the protocol level using associated types. Function-level generics are not currently supported. If you need generic capabilities, consider using associated types in the protocol.\n- **Child Protocols Cannot Mock Parent Requirements**: When mocking protocols that inherit from other protocols, the `@Mocked` macro will not automatically generate implementations for the inherited protocol requirements.\n- **No Support for `@` Annotations**: Attributes such as `@MainActor` are not currently supported in mock generation.\n\n## Contributing\n\nContributions are welcome! If you have suggestions, issues, or improvements, feel free to open a pull request or issue on the [GitHub repository](https://github.com/0xLeif/Mocked).\n\n## License\n\nThis project is licensed under the MIT License. See the [LICENSE](LICENSE) file for more information.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F0xleif%2Fmocked","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F0xleif%2Fmocked","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F0xleif%2Fmocked/lists"}