使用 rspec 在 ruby 元编程中模拟动态生成的类
我是 TDD 和元编程的新手,所以请耐心等待!
我有一个 Reporter 类(用于包装 Garb ruby gem),它将动态生成一个新的报告类,并在我点击 method_missing 时将其分配给 GoogleAnalyticsReport 模块。主要要点如下:
# Reporter.rb
def initialize(profile)
@profile = profile
end
def method_missing(method, *args)
method_name = method.to_s
super unless valid_method_name?(method_name)
class_name = build_class_name(method_name)
klass = existing_report_class(class_name) ||
build_new_report_class(method_name, class_name)
klass.results(@profile)
end
def build_new_report_class(method_name, class_name)
klass = GoogleAnalyticsReports.const_set(class_name, Class.new)
klass.extend Garb::Model
klass.metrics << metrics(method_name)
klass.dimensions << dimensions(method_name)
return klass
end
报告者期望的“配置文件”类型是 Garb::Management::Profile。
为了测试这个 Reporter 类上的一些私有方法(例如 valid_method_name?或 build_class_name),我相信我想用 rspec 来模拟配置文件,因为它不是我感兴趣的细节。
但是,对 klass 的调用.结果(@profile) - 正在执行并杀死我,所以我没有存根我在元部分扩展的 Garb::Model。
到目前为止,这是我如何嘲笑和存根的......规范实现当然并不重要:
describe GoogleAnalyticsReports::Reporter do
before do
@mock_model = mock('Garb::Model')
@mock_model.stub(:results) # doesn't work!
@mock_profile = mock('Garb::Management::Profile')
@mock_profile.stub!(:session)
@reporter = GoogleAnalyticsReports::Reporter.new(@mock_profile)
end
describe 'valid_method_name' do
it 'should not allow bla' do
@reporter.valid_method_name?('bla').should be_false
end
end
end
有谁知道我如何对 results 方法的调用存根我新创建的班级?
任何指示将不胜感激!
〜斯图
I'm new to TDD and metaprogramming so bear with me!
I have a Reporter class (to wrap the Garb ruby gem) that will generate a new report class on-the-fly and assign it to a GoogleAnalyticsReport module when I hit method_missing. The main gist is as follows:
# Reporter.rb
def initialize(profile)
@profile = profile
end
def method_missing(method, *args)
method_name = method.to_s
super unless valid_method_name?(method_name)
class_name = build_class_name(method_name)
klass = existing_report_class(class_name) ||
build_new_report_class(method_name, class_name)
klass.results(@profile)
end
def build_new_report_class(method_name, class_name)
klass = GoogleAnalyticsReports.const_set(class_name, Class.new)
klass.extend Garb::Model
klass.metrics << metrics(method_name)
klass.dimensions << dimensions(method_name)
return klass
end
The type of 'profile' that the Reporter expects is a Garb::Management::Profile.
In order to test some of my private methods on this Reporter class (such as valid_method_name? or build_class_name), I believe I want to mock the profile with rspec as it's not a detail that I'm interested in.
However, the call to klass.results(@profile) - is executing and killing me, so I haven't stubbed the Garb::Model that I'm extending in my meta part.
Here's how I'm mocking and stubbing so far... the spec implementation is of course not important:
describe GoogleAnalyticsReports::Reporter do
before do
@mock_model = mock('Garb::Model')
@mock_model.stub(:results) # doesn't work!
@mock_profile = mock('Garb::Management::Profile')
@mock_profile.stub!(:session)
@reporter = GoogleAnalyticsReports::Reporter.new(@mock_profile)
end
describe 'valid_method_name' do
it 'should not allow bla' do
@reporter.valid_method_name?('bla').should be_false
end
end
end
Does anyone know how I can stub the call to the results method on my newly created class?
Any pointers will be greatly appreciated!
~ Stu
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
而不是:
我认为您想要执行以下操作:
这将删除 Garb::Model 的任何实例以返回结果。您需要这样做,因为您实际上并未将 @mock_model 传递到任何将使用它的类/方法中,因此您必须更通用一些。
Instead of:
I think you want to do:
This will stub out any instance of Garb::Model to return results. You need to do this because you are not actually passing @mock_model into any class/method that will use it so you have to be a bit more general.