Bra*_*don 2 testing rspec ruby-on-rails mocking stubbing
晚上好,
我正在尝试在我的"Simulation"类中测试一个相当长的方法,该类调用类方法"is_male_alive?" 和"is_female_alive?" 在我的"年龄"课上几百次.这些类方法的返回值基于统计信息,我想将它们存根以返回特定值,以便我的测试每次都运行相同.
Age.rb:
...
def is_male_alive?(age)
return false if age > 119
if (age < 0 || age == nil || age == "")
return false
end
death_prob = grab_probability_male(age)
rand_value = rand
rand_value > death_prob
end
...
Run Code Online (Sandbox Code Playgroud)
(女性版本与一些不同的常量基本相同)
在我的"模拟"课程中,我执行以下操作:
def single_simulation_run
...
male_alive = Age.is_male_alive?(male_age_array[0])
female_alive = Age.is_female_alive?(female_age_array[0])
...
end
Run Code Online (Sandbox Code Playgroud)
在模拟的每次迭代中 - 基本上它只是传递一个年龄(例如is_male_alive?(56))并返回true或false.
我想删除这两种方法,以便:
我已经尝试了以下内容,看看我是否有能力将其存根(simulation_spec.rb):
Age.should_receive(:is_male_alive?).exactly(89).times
results = @sim.send("generate_asset_performance")
Run Code Online (Sandbox Code Playgroud)
但是我收到以下错误:
Failure/Error: Age.should_receive(:is_male_alive?).exactly(89).times
(<Age(id: integer, age: integer, male_prob: decimal, female_prob: decimal) (class)>).is_male_alive?(any args)
expected: 89 times
received: 0 times
Run Code Online (Sandbox Code Playgroud)
我也不知道如何设置它以便根据参数动态生成存根返回值.有没有办法用proc做到这一点?
有没有办法模拟整个Age类(而不是仅仅模拟Age类的单个实例?)
谢谢你的帮助!!
更新1
看起来这个方法被调用存在问题......这实在令人困惑.为了真正看到它是否被调用,我向方法中引发了"引发ArgumentError".
开发环境(控制台):
1.9.3p125 :003 > sim = Simulation.last
1.9.3p125 :004 > sim.generate_results
---> ArgumentError: ArgumentError
Run Code Online (Sandbox Code Playgroud)
所以它显然是在开发环境中调用这个方法,因为它抛出了争论的错误.
在我的测试中再次使用它,它仍然说该方法没有被调用...我正在使用下面的代码:
Age.should_receive(:is_male_alive?).with(an_instance_of(Fixnum)).at_least(:once) { |age| age < 75 }
Run Code Online (Sandbox Code Playgroud)
我也尝试过这个
Age.should_receive(:is_male_alive?).with(an_instance_of(Fixnum)).at_least(:once) { raise ArgumentError }
Run Code Online (Sandbox Code Playgroud)
有什么想法吗?
你可以使用块.请参阅rspec的消息期望文档中的任意处理:http: //rubydoc.info/gems/rspec-mocks/frames
Age.should_receive(:is_male_alive?).with(an_instance_of(Fixnum)).at_least(:once) { |age| age < 75 }
Age.should_receive(:is_female_alive?).with(an_instance_of(Fixnum)).at_least(:once) { |age| age < 80 }
Run Code Online (Sandbox Code Playgroud)