Mik*_*ike 6 ruby tdd rspec stub load-path
我有两节课:
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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
因为我想使用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
Run Code Online (Sandbox Code Playgroud)
运行时,此测试有效bundle exec rspec spec/models/report_spec.rb.
但是,当我运行bundle exec rake spec错误时,此测试失败superclass mismatch for class Sale (TypeError).我知道错误正在发生,因为Tap是由sale.rb规范中的内联定义的.
所以我的问题是,如果没有定义该类,有一种方法可以将Stub(或Mock或Double)作为一个类吗? 这将允许我删除内联class Sale; end,这感觉就像一个黑客.
如果没有,我如何设置我的测试,使他们无论我跑bundle exec rspec还是正常运行bundle exec rake spec?
如果没有,我写快速测试的方法是错误的吗?!
最后,我不想使用Spork.谢谢!
最近添加的 RSpecstub_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
Run Code Online (Sandbox Code Playgroud)
您可能还想使用rspec-fire来使用测试替身来代替在加载真实类的情况下运行测试时(例如,当您运行测试套件时)Sale自动检查真实类上存在的所有模拟/存根方法:SaleSale
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
Run Code Online (Sandbox Code Playgroud)
如果您total_for_duration在真实Sale类上重命名,则当您模拟该方法时,rspec-fire 会给您一个错误,因为它在真实类上不存在。