我正在努力强制执行封装(但可能做得不好),并希望在Rspec中测试代码。 Customer类在工厂类中实例化时将采用类Object(作为klass)。通过尚未存在的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
感谢任何帮助!
答案 0 :(得分:1)
使用be_a
,您正在测试klass
是klass
的实例,这可能不是您想要的。
在我看来,在测试initialize
方法和klass
的getter(这是你正在做的,实际上)时,你应该只对确认发送的内容感兴趣之后可以阅读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
需要一个klass。Object
中使用fetch
作为默认设置可能不是您想要的。首先,您可能希望它们是某个类的实例,而不是类对象。Customer
类实例的工作吗?如果要确保可以根据用户输入实例化任何类型的抽象顺序,那么单独的OrderCreator
类可能更合适吗?此类可以接受用户数据和订单类以及受影响的客户。