Skip to content

[Feature] Support unchecked Sendable mocks #86

@berbs-fetch

Description

@berbs-fetch

Use Case

Use @Mocked for a protocol that is Sendable but the default generated mock is not Sendable and fails the compiler.

Feature Proposal

I would like to see @Mocked support an interface like this:

@Mocked 
protocol MyInterface: Sendable {
    func myFunction(arg: Any)
}

While this is technically valid, and the implementation will be Sendable, the generated mock is NOT sendable.

The error is something like:

Stored property '__doSomething' of 'Sendable'-conforming class 'TestMock' has non-sendable type '(method: MockVoidMethodWithParameters<Any>, invoke: (Any) -> Void, reset: () -> Void)'

The proposal is to add an argument to the @Mocked macro to include @unchecked in the generated code.

@Mocked(sendability: .unchecked | .checked (default))

Note

Not all protocols implement Sendable and this new argument would only apply if the underlying protocol implements Sendable. That will have to be thought of when analyzing the syntax tree of the protocol being mocked.

Alternatives Considered

  • I shouldn't use type Any and actually have a Sendable type.
    • In my context this would be a pain b/c it is types: NSArray, NSDictionary, NSNull, NSNumber, NSDate. I can't cast these as Sendable b/c the objc types don't implement that protocol.
    • My interface is based on what Apple gives me, and their type is Any
  • Manually implementing the mock using @MockedMembers and @unchecked Sendable
@MockedMembers
final class TestMock: Test, @unchecked Sendable {
    func doSomething(foo: Any)
}

Additional Context

My real life use case is with WebKit.

I have this actual protocol that is converting the type Any to a Sendable type T.

@Mocked 
public protocol WebMessageDecoder: Sendable {
    func decode<T: Decodable & Sendable>(_ type: T.Type, from body: Any) throws -> T
}

Code of Conduct

  • I agree to follow this project's Code of Conduct

Metadata

Metadata

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions