Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stubbing a throwing async function shows compile error #302

Open
2 of 4 tasks
alschmut opened this issue May 20, 2022 · 2 comments
Open
2 of 4 tasks

Stubbing a throwing async function shows compile error #302

alschmut opened this issue May 20, 2022 · 2 comments
Labels
framework bug Breaks tests or user testing code

Comments

@alschmut
Copy link

New Issue Checklist

Overview

Stubbing a throwing async function to throw an error shows a compile error:

givenSwift(await bird.canFly()).willThrow(MockError())
// Compiler error:
// Cannot convert value of type 'Mockable<ThrowingAsyncFunctionDeclaration, () async throws -> Bool, Bool>' 
// to expected argument type    'Mockable<ThrowingFunctionDeclaration, () async throws -> Bool, Bool>'

If I look into the mockingbird code, it seems the function willThrow(_:) is not available for the ThrowingAsyncFunctionDeclaration (see Stubbing.swift#L399)

extension StubbingManager where DeclarationType == ThrowingAsyncFunctionDeclaration {
    public func willThrow(_ error: Error) -> Self { ... }
}

Example

func test_bird_can_not_fly_after_shaking_tree() async throws {
    let bird = mock(Bird.self)
    let tree = Tree(with: bird)
    givenSwift(await bird.canFly()).willThrow(MockError()) // compile error

    try await tree.shake()

    verify(bird.fly()).wasNeverCalled()
}

protocol Bird {
    func canFly() async throws -> Bool
    func fly()
}

struct MockError: Error {}

class Tree {
    private let bird: any Bird
    
    init(with bird: any Bird) {
        self.bird = bird
    }
    
    func shake() async throws {
        if try await bird.canFly() {
            bird.fly()
        }
    }
}

Expected Behavior

When stubbing a throwing async function to throw an error
Then I expect to see no compile error
And I expect the function to throw an error, whenever it is called by the test

Environment

  • Mockingbird CLI version: 0.17.0 (not sure why this is on 0.17.0, the resolved SPM package in Xcode has version 0.20.0)
  • Xcode and Swift version: 5.6
  • Package manager: SPM package
  • Unit testing framework: XCTest
  • Custom configuration
    • Mockingbird ignore files
    • Supporting source files
@alschmut alschmut added the framework bug Breaks tests or user testing code label May 20, 2022
@ailtonvivaz
Copy link
Contributor

ailtonvivaz commented May 23, 2022

Unfortunately, I was unable to make it work, but there is a workaround for it.
You can use:

givenSwift(await bird.canFly()).will { throw MockError() }

or even:

given(await bird.canFly()) ~> { throw MockError() }

@oleksandryevdokymov
Copy link

oleksandryevdokymov commented Jun 23, 2022

I have the same issue.
But a bit different workaround works for me based on @ailtonvivaz answer.
In my case error is enum that conforms Error protocol.
It looks like:

givenSwift(await ache.getContacts()).will { _ in throw error }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
framework bug Breaks tests or user testing code
Projects
None yet
Development

No branches or pull requests

3 participants