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
相关产品推荐
相关产品推荐

