Pharo中如何基于源码生成带方法体的测试方法
问题分析
你的核心问题是未针对目标方法的参数列表生成关联测试逻辑,反而错误遍历#setter协议选择器,导致生成代码与目标方法脱节。以下是针对性修正方案:
核心解决思路
- 提取目标方法的参数元信息(数量、参数名)
- 将传入的测试参数值列表与方法参数一一绑定
- 生成包含变量声明、参数赋值、目标方法调用、断言语句的完整测试方法体
修改后的代码实现
buildSelectorFor: aMethod ^ String streamContents: [:stream || capitalize | capitalize := true. stream << 'test'. aMethod selector do: [:char | char = $: ifTrue: [ capitalize := true ] ifFalse: [ capitalize ifTrue: [ capitalize := false. stream << char asUppercase. ] ifFalse:[ stream << char ]]]] writeTestMethod: aMethod with: testArguments | paramNames selectorParts | paramNames := aMethod argumentNames. selectorParts := aMethod selector splitOn: $:. selectorParts := selectorParts allButLast. "移除拆分后末尾的空元素" ^ String streamContents: [:stream | "写入测试方法选择器" stream << (self buildSelectorFor: aMethod); cr. "写入方法体缩进" stream << ' '. "声明局部变量" stream << '| '. stream << 'testInstance '. paramNames do: [:name | stream << name, 'Value ']. stream << '|'; cr. "初始化测试实例" stream << ' testInstance := ' << aMethod methodClass name << ' new.'; cr. "为每个参数赋值" paramNames withIndexDo: [:name :index | stream << ' ' << name, 'Value := ' << (testArguments at: index) asString << '.'; cr]. "调用目标方法" stream << ' testInstance '. selectorParts withIndexDo: [:part :index | stream << part << ': ' << (paramNames at: index), 'Value ']. stream << '.'; cr. "生成断言(假设setter对应同名无冒号的getter)" selectorParts withIndexDo: [:part :index | stream << ' self assert: testInstance ' << part << ' equals: ' << (paramNames at: index), 'Value.'; cr]]
执行示例
调用代码:
self writeTestMethod: Car>>#speed:mark: with: #(100 'A')
生成的测试代码:
testSpeedMark | testInstance speedValue markValue | testInstance := Car new. speedValue := 100. markValue := 'A'. testInstance speed: speedValue mark: markValue. self assert: testInstance speed equals: speedValue. self assert: testInstance mark equals: markValue.
关键细节说明
aMethod argumentNames:直接获取目标方法的参数名(如#speed:mark:对应#('speed' 'mark'))selectorParts:将选择器按:拆分后清理无效元素,用于构建消息发送和断言语句- 使用
String streamContents替代字符串拼接,避免格式混乱和缩进错误 - 测试参数列表
testArguments需与目标方法参数数量严格对应
内容的提问来源于stack exchange,提问作者Mansour Faouziel
相关产品推荐
相关产品推荐

