ruby – 使用和不使用Rails进行快速(Rspec)测试
我有两节课:
1.Sale是ActiveRecord的子类;它的工作是将销售数据保存到数据库中. class Sale < ActiveRecord::Base def self.total_for_duration(start_date,end_date) self.count(conditions: {date: start_date..end_date}) end #... end 2.SalesReport是一个标准的Ruby类;它的工作是生成和绘制有关销售的信息. class SalesReport def initialize(start_date,end_date) @start_date = start_date @end_date = end_date end def sales_in_duration Sale.total_for_duration(@start_date,@end_date) end #... end 因为我想使用TDD并且我希望我的测试运行得非常快,所以我为SalesReport编写了一个不加载Rails的规范: require_relative "../../app/models/sales_report.rb" class Sale; end # NOTE I have had to re-define Sale because I don't want to # require `sale.rb` because it would then require ActiveRecord. describe SalesReport do describe "sales_in_duration" do it "calls Sale.total_for_duration" do Sale.should_receive(:total_for_duration) SalesReport.new.sales_in_duration end end end 当我运行bundle exec rspec spec / models / report_spec.rb时,此测试有效. 但是,当我运行bundle exec rake spec并且类Sale(TypeError)的错误超类不匹配时,此测试失败.我知道错误正在发生,因为Tap是由sale.rb定义并在规范中内联. 所以我的问题是,如果没有定义该类,有一种方法可以将Stub(或Mock或Double)作为一个类吗?这将允许我删除内联类Sale;结束,这感觉就像一个黑客. 如果没有,如何运行bundle exec rspec或bundle exec rake spec,我如何设置我的测试以使它们正确运行? 如果没有,我写快速测试的方法是错误的吗?! 最后,我不想使用Spork.谢谢! 解决方法
RSpec最近添加的stub_const专门针对以下情况设计:
describe SalesReport do before { stub_const("Sale",Class.new) } describe "sales_in_duration" do it "calls Sale.total_for_duration" do Sale.should_receive(:total_for_duration) SalesReport.new.sales_in_duration end end end 您可能还想使用rspec-fire来代替Sale来使用测试双精度来自动检查真实Sale类中存在的所有模拟/存根方法在运行带有加载的真实Sale类的测试时(例如,当您运行测试套件时) : require 'rspec/fire' describe SalesReport do include RSpec::Fire describe "sales_in_duration" do it "calls Sale.total_for_duration" do fire_replaced_class_double("Sale") Sale.should_receive(:total_for_duration) SalesReport.new.sales_in_duration end end end 如果在真正的Sale类上重命名total_for_duration,则在模拟方法时rspec-fire会给出错误,因为它在实际类中不存在. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |