同一RSpec示例组内能否用let重复声明同一辅助方法以返回不同值?
在同一RSpec示例组内为同一let变量设置不同返回值(无需新增context)
不行,默认情况下,RSpec的let是在示例组级别生效的——同一个示例组里后定义的let会直接覆盖前面的,所以你原代码里所有期望都会使用最后那个my_var = 1的值,达不到分别用0和1的效果。不过不用新增context也能解决,以下是几种可行方案:
方案一:在每个it块内直接创建实例
跳过外部的let和subject,直接在每个测试示例里手动创建带不同参数的对象实例,最直接易懂:
describe MyClass do describe '#my_method' do context 'some context' do it 'behaves correctly when my_var is 0' do my_obj = described_class.new(0) expect(my_obj.my_method).to eq(expected_result_for_0) end it 'behaves correctly when my_var is 1' do my_obj = described_class.new(1) expect(my_obj.my_method).to eq(expected_result_for_1) end end end end
方案二:用实例变量配合let动态赋值
通过实例变量让let的返回值在不同it块里动态变化,虽然用了实例变量(RSpec通常推荐let),但能满足需求:
describe MyClass do subject(:my_obj) { described_class.new(my_var) } describe '#my_method' do context 'some context' do let(:my_var) { @custom_var || 0 } it 'uses my_var = 0' do @custom_var = 0 expect(my_obj.my_method).to eq(result_for_0) end it 'uses my_var = 1' do @custom_var = 1 expect(my_obj.my_method).to eq(result_for_1) end end end end
方案三:使用共享示例(shared_examples)封装逻辑
如果测试逻辑重复,可以用共享示例来复用代码,不用新增context就能传递不同参数:
describe MyClass do describe '#my_method' do context 'some context' do shared_examples 'my_method with my_var' do |input, expected| it "returns #{expected} when my_var is #{input}" do my_obj = described_class.new(input) expect(my_obj.my_method).to eq(expected) end end include_examples 'my_method with my_var', 0, result_for_0 include_examples 'my_method with my_var', 1, result_for_1 end end end
内容的提问来源于stack exchange,提问作者Lorenzo Zabot
相关产品推荐
相关产品推荐

