所以我正在编写一个方法,这会导致向类添加一些代码(特别是选择哈希值并创建一个arel风格的default_scope
)。虽然我只是简单地使用MyClass.send将代码送到课堂上,但我觉得instance_eval
会更清晰,更清晰。
# test
let(:hash) { {order: "my_column desc"} }
let(:arel) { Proc.new{ order(hash[:order]) } }
it "converts options hash to arel calls" do
MyClass.send(:my_translator_method, hash)
end
# method
def self.my_translator_method(hash)
code = method_to_convert_options_to_arel
self.instance_eval <<CODE
default_scope #{code}
CODE
end
问题是我不确定如何挂钩进入该类以确定它是否按照预期的方式进行了更改。
答案 0 :(得分:1)
首先,为什么你不能这样做:
self.send(:default_scope, code)
而不是使用元编程?
其次,你应该总是测试行为,而不是实现:
correct_ordered_elements = [.....]
Myclass.all.should == correct_ordered_elements
答案 1 :(得分:1)
我会建议这样的事情:
it "converts options hash to arel calls" do
expect { MyClass.default_scope }.to raise_error
MyClass.my_translator_method hash
expect { MyClass.default_scope }.to_not raise_error
end
然后,为了更好的衡量 - 检查范围是否正确:
it "creates an ordered scope" do
MyClass.my_translator_method hash
expect(MyClass.default_scope.to_a).to eq MyClass.order("my_column desc").to_a
end
答案 2 :(得分:1)
你应该能够对班级单身人士期望这样做:
let(:code) { method_to_convert_options_to_arel }
let(:hash) { {order: "my_column desc"} }
it "sets the default scope" do
expect(MyClass).to receive(:default_scope).with(code)
MyClass.my_translator_method(hash)
end
我认为你不应该在这里测试范围本身 - 为产生Arel代码的方法编写一个单独的测试。