我正在努力实施封装(但可能做得不好),并想在Rspec中测试代码。当在工厂类中实例化Customer类时,它将采用一个Object类(作为容器)。通过尚不存在的UI,客户将创建一个订单。
我当前的测试如下。我只想确认订单是Order类。
describe 'Customer' do
let(:customer){Customer.new}
let(:customer_with_instantiation){Customer.new(:klass=>order, :name=>'Oscar Wilde', :number=>'0234567')}
let(:order){double :order, :name=>:order}
it 'klass object to be the order class when customer is instantiated with a klass attribute' do
expect(customer_with_instantiation.klass).to be_a(order)
end
end
类代码如下:
class Customer
attr_accessor :name, :number, :klass
DEFAULT_CUSTOMER_ORDER = {:order_detail => [{ :dish=>"",
:item_count=>0 }],
:order_total_cost=>0 }
def initialize(options={})
@name=options.fetch(:name, "")
@number=options.fetch(:number, "")
@klass=options.fetch(:klass, Object)
@customer_order=DEFAULT_CUSTOMER_ORDER
end
def place_order(menu)
#requires user input
customer_order=klass.new({:order_detail => [{:dish => :pizza, :item_count => 3},
{:dish => :burger, :item_count => 3}],
:order_total_cost => 210})
klass.test_customer_order(customer_order, self)
end
end
class Order
attr_reader :order_detail, :order_total_cost
attr_accessor :total_check
def initialize(options={})
@order_detail=options.fetch(:order_detail, Object)
@order_total_cost=options.fetch(:order_total_cost, Object)
end
def self.test_customer_order(customer_order, customer, menu, assistant)
customer_order.total_check = 0
customer_order.order_detail.each do |order_item|
menu.dishes.each do |dish|
if order_item[:dish]==dish.name
customer_order.total_check += dish.price*order_item[:item_count]
end
end
end
assistant.take_order(customer_order, customer, customer_order.total_check)
end
end
任何帮助表示感谢!
最佳答案
通过使用be_a
,您正在测试klass
是klass
的实例,可能不是您想要的。
在我看来,当测试initialize
方法和klass
的吸气剂(实际上是在做什么)时,您应该只对确认发送到Customer.new
的内容能够被读取感兴趣。然后。
所以也许是这样的:
class Foo
attr_reader :klass
def initialize(args)
@klass = args.fetch(:klass)
end
end
describe Foo do
describe "#initialize" do
let(:klass) { double }
let(:instance) { Foo.new(klass: klass)}
it "sets klass" do
expect(instance.klass).to eq(klass)
end
end
end
一些一般要点:
如果要测试订单是否为
klass
的实例,则可能应该重写代码以使其更易于测试在这种情况下,
klass
不是一个非常有用的名称。目前尚不清楚为什么Customer
需要一个杯子。您想使订单与客户脱钩,但是客户显然正在对订单界面进行一些假设。你真的有成就吗?
我建议不要将测试方法放在类本身中,而应该放在测试文件中。
在
Object
中使用fetch
作为默认值可能不是您想要的。首先,您可能希望它们是某个类的实例,而不是类对象。Customer
类的实例创建订单真的是工作吗?如果要确保可以根据用户输入实例化任何种类的抽象顺序,那么也许单独的OrderCreator
类更合适?此类可以接受用户数据和订单类别以及受影响的客户。关于ruby - 如何在Rspec中 stub Class对象?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28538811/