Kolos65 / Mockable

A Swift macro driven auto-mocking library.
MIT License
199 stars 14 forks source link

Async let mocks causing crashes #30

Closed emadhegab closed 3 months ago

emadhegab commented 3 months ago

We have issue with async let . here is an example :

@Mockable
public protocol PersonProtocol {
    var name: String { get set }
}

public final class TestCrash {
    let person: PersonProtocol

    init(person: PersonProtocol) {
        self.person = person
    }

    private func firstFunc() async -> String  {
        return person.name
    }

    private func secondFunc() async -> String  {
        return person.name
    }

    private func thirdFunc() async -> String {
        return person.name
    }

    @MainActor
    func loadAll() async {
        async let first = firstFunc()
        async let second = secondFunc()
        async let third = thirdFunc()

        let (_,_,_) = await (first, second, third)
    }
 }
import XCTest
import MockableTest
@testable import FinanceUI

final class CrashTestCase: XCTestCase {

    func testCrash() async {
        let person = MockPersonProtocol()
        given(person).name.willReturn("")

        let sut = TestCrash(person: person)

        await sut.loadAll()
    }
}

with that we get a crash

image

Kolos65 commented 3 months ago

Can you confirm this with the latest version too?

Kolos65 commented 3 months ago

@emadhegab I was able to repro this only in 0.0.3, the crash is not present in 0.0.4.

However, this issue highlights an important shortcoming: the current Mocker implementation was not fully thread-safe.

31 addresses this by synchronising all state mutations