You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Sourcery生成带关联类型的协议Mock输出不一致,如何确保一致性?

解决Sourcery为带关联类型和约束的协议生成Mock时输出不一致的问题

我在iOS项目中使用Sourcery为继承带关联类型协议的Protocol生成Mock,输入完全一致,但Sourcery的输出却不稳定——有时能生成正确的Mock,有时仅生成一个只包含init方法的空类。

代码设置

public protocol Foo {
    associatedtype Input
    associatedtype Output
    associatedtype Failure: Error

    @discardableResult
    func bar(parameters: Input) -> AnyPublisher<Output, Failure>
}

// sourcery: AutoMockable
public protocol Bar: Foo
where Input == String,
      Output == Bool,
      Failure == Never { }

错误输出示例

public class Bar: Foo {
    public init() {}
}

解决方案

问题根源在于自定义的AutoMockable.stencil模板对带关联类型约束的继承协议解析不稳定,可通过以下步骤修复:

  • 显式声明关联类型:修改模板中生成Mock类的部分,强制遍历并声明协议的关联类型(包括通过where子句约束的具体类型),避免依赖Sourcery的自动推断。示例模板代码:

    public class {{ name }}Mock: {{ name }} {
        {% for associatedType in associatedTypes %}
        public typealias {{ associatedType.name }} = {{ associatedType.typeName }}
        {% endfor %}
        
        public init() {}
        // 后续方法Mock实现
    

    需确保模板能正确获取协议通过约束指定的关联类型,必要时可访问inheritedAssociatedTypes来获取父协议的关联类型信息。

  • 包含继承的方法:模板默认可能只处理当前协议定义的方法,需改为遍历allMethods(包含父协议继承的方法),确保bar方法被生成Mock实现。修改模板中的方法遍历逻辑:

    {% for method in allMethods %}
    // 生成方法的调用计数器、返回值存根等Mock代码
    {% endfor %}
    
  • 清空Sourcery缓存:缓存异常可能导致解析错误,执行Sourcery时添加--clean参数强制清空缓存:

    sourcery --clean
    
  • 锁定Sourcery版本:不同版本的Sourcery对关联类型约束的解析逻辑存在差异,锁定稳定版本(如2.0及以上)可避免版本波动带来的问题。

内容的提问来源于stack exchange,提问作者Levan Karanadze

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 07:27:20