我知道你们中的一些人已经怀疑我的理智了。我有一个ActiveRecord
类,它使用缺少的方法来挖掘它所拥有的JSON属性。
# app/models/request_interactor.rb
...
def method_missing(method_sym, *arguments, &block)
return self.request_params[method_sym.to_s] if self.request_params[method_sym.to_s]
super
end
测试看起来像这样
before(:each) do
@ri = RequestInteractor.create(result: {magic_school: true, magic_learnt: 'all things magical'}, request_params: {application_id: 34, school_id: 20, school_name: 'Hogwarts', course_name: 'Defence against the Dark Arts.'})
end
it 'should respond to attributes set in the request parameters' do
expect(@ri).to respond_to(:school_name)
expect(@ri.school_name).to eq('Hogwarts')
end
我尝试在测试中绑定,@ri.school_name
将eq 'Hogwarts'
,但当它运行responds_to
时,它将失败,说没有这样的方法!肮脏,肮脏的骗子!
我尝试在模型中做这样的事情:
def respond_to?(method, include_private = false)
super || self.respond_to?(method, include_private)
end
但是由于递归,这将导致堆栈级别太深,因为递归..所以现在我的命运掌握在你手中!启发我哦,伟大的。我如何测试缺失方法的响应。
答案 0 :(得分:3)
使用respond_to_missing
。更多信息here。
现在,所有这一切都在说。如果你问我,你的模式看起来仍然是黑客。
<强> Refactors 强>
Ruby有很多方法来清理它。
使用委托模式
delegate :method_name, :to => :request_params
(检查doc中的其他选项)。这可以通过在对象中使用方法来解决您的问题,以便respond_to?
能够正常工作,并且您将避免覆盖method_missing
。
设置request_params
(对访问者进行元编程)时生成访问方法。
使用OpenStruct,因为可以使用Hash
request_params
初始化这些内容。如果你在上面添加委托,你应该很酷。
希望这有帮助。