Giter Site home page Giter Site logo

ramyaimansabry / swift-spyable Goto Github PK

View Code? Open in Web Editor NEW

This project forked from matejkob/swift-spyable

0.0 0.0 0.0 127 KB

Swift macro that simplifies and automates the process of creating spies for testing

License: MIT License

Swift 100.00%

swift-spyable's Introduction

Spyable

GitHub Workflow Status Codecov

A powerful tool for Swift that simplifies and automates the process of creating spies for testing. Using the @Spyable annotation on a protocol, the macro generates a spy class that implements the same interface as the protocol and keeps track of interactions with its methods and properties.

Overview

A "spy" is a specific type of test double that not only replaces a real component, but also records all interactions for later inspection. It's particularly useful in behavior verification, where the interaction between objects, rather than the state, is the subject of the test.

The Spyable macro is designed to simplify and enhance the usage of spies in Swift testing. Traditionally, developers would need to manually create spies for each protocol in their codebase โ€” a tedious and error-prone task. The Spyable macro revolutionizes this process by automatically generating these spies.

When a protocol is annotated with @Spyable, the macro generates a corresponding spy class that implement this protocol. This spy class is capable of tracking all interactions with its methods and properties. It records method invocations, their arguments, and returned values, providing a comprehensive log of interactions that occurred during the test. This data can then be used to make precise assertions about the behavior of the system under test.

TL;DR

The Spyable macro provides the following functionality:

  • Automatic Spy Generation: No need to manually create spy classes for each protocol. Just annotate the protocol with @Spyable, and let the macro do the rest.
  • Interaction Tracking: The generated spy records method calls, arguments, and return values, making it easy to verify behavior in your tests.
  • Swift Syntax: The macro uses Swift syntax, providing a seamless and familiar experience for Swift developers.

Quick start

To get started, import Spyable: import Spyable, annotate your protocol with @Spyable:

@Spyable
protocol ServiceProtocol {
    var name: String { get }
    func fetchConfig(arg: UInt8) async throws -> [String: String]
}

This will generate a spy class named ServiceProtocolSpy that implements ServiceProtocol. The generated class includes properties and methods for tracking the number of method calls, the arguments passed, and whether the method was called.

class ServiceProtocolSpy: ServiceProtocol {
    var name: String {
        get { underlyingName }
        set { underlyingName = newValue }
    }
    var underlyingName: (String)!
    
    var fetchConfigArgCallsCount = 0
    var fetchConfigArgCalled: Bool {
        return fetchConfigArgCallsCount > 0
    }
    var fetchConfigArgReceivedArg: UInt8?
    var fetchConfigArgReceivedInvocations: [UInt8] = []
    var fetchConfigArgReturnValue: [String: String]!
    var fetchConfigArgClosure: ((UInt8) async throws -> [String: String])?

    func fetchConfig(arg: UInt8) async throws -> [String: String] {
        fetchConfigArgCallsCount += 1
        fetchConfigArgReceivedArg = (arg)
        fetchConfigArgReceivedInvocations.append((arg))
        if fetchConfigArgClosure != nil {
            return try await fetchConfigArgClosure!(arg)
        } else {
            return fetchConfigArgReturnValue
        }
    }
}

Then, in your tests, you can use the spy to verify that your code is interacting with the service dependency of type ServiceProtocol correctly:

func testFetchConfig() async throws {
    let serviceSpy = ServiceProtocolSpy()
    let sut = ViewModel(service: serviceSpy)

    serviceSpy.fetchConfigArgReturnValue = ["key": "value"]

    try await sut.fetchConfig()

    XCTAssertEqual(serviceSpy.fetchConfigArgCallsCount, 1)
    XCTAssertEqual(serviceSpy.fetchConfigArgReceivedInvocations, [1])

    try await sut.saveConfig()

    XCTAssertEqual(serviceSpy.fetchConfigArgCallsCount, 2)
    XCTAssertEqual(serviceSpy.fetchConfigArgReceivedInvocations, [1, 1])
}

Examples

This repo comes with an example of how to use Spyable. You can find it here.

Documentation

Soon.

Installation

Warning: Xcode beta 15.x command line tools are required.

For Xcode project

If you are using Xcode beta 15.x command line tools, you can add swift-spyable macro to your project as a package.

https://github.com/Matejkob/swift-spyable

For Swift Package Manager

In Package.swift add:

dependencies: [
  .package(url: "https://github.com/Matejkob/swift-spyable", from: "0.1.0")
]

and then add the product to any target that needs access to the macro:

.product(name: "Spyable", package: "swift-spyable"),

License

This library is released under the MIT license. See LICENSE for details.

swift-spyable's People

Contributors

matejkob avatar coffmark avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.