实例_sval的Rspec测试结果

时间:2014-03-12 17:30:39

标签: ruby rspec metaprogramming

所以我正在编写一个方法,这会导致向类添加一些代码(特别是选择哈希值并创建一个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

问题是我不确定如何挂钩进入该类以确定它是否按照预期的方式进行了更改。

3 个答案:

答案 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代码的方法编写一个单独的测试。