只是一个简单的问题。我有一个看起来像这样的测试规范......
require 'user'
describe "Integration" do
let(:user) { User.new(voucher) }
context 'no voucher' do
let(:voucher) { nil }
context 'no voucher' do
let(:voucher) { nil }
it 'should bill default price all the time' do
user.bill
expect(user.orders[0].billed_for).to eql 6.95
... ...
end
end
context 'vouchers' do
describe 'default vouchers' do
let(:voucher) { Voucher.create(:default, credit: 15) }
it 'should not bill user if has a remaining credit' do
user.bill
expect(user.orders[0].billed_for).to eql 0.0
... ...
end
end
我有一个非常简单的凭证类atm
class Voucher
attr_accessor :credit, :type
def self.create(type, *attrs)
@type = type
end
def billed_for
Random.new.rand(0..4)
end
end
现在奇怪的是,如果我尝试通过用户存储凭证类的变量,它会将其抛出并输出未定义的变量。对象绝对不是,当我检查它告诉我它是一个阵列的类型时!打印这个产生的东西像...... [{:credit => 15}] [{:discount => 50,:number => 3}] 为什么会这样?我在用户类中设置了错误吗?我的用户类位于
之下require 'order'
require 'voucher'
class User
attr_accessor :voucher, :orders
def initialize(voucher = nil, orders =[])
@orders = orders
@voucher = voucher.nil? ? nil : voucher
end
答案 0 :(得分:1)
您的voucher.create方法实际上并未创建优惠券。如果您检查Voucher.create
的返回结果的类,则应该看到Symbol
:
Voucher.create(:default).class #=> Symbol
这是因为您返回设置@type = type
的结果,其中类型为:default
,其类别为Symbol
。我不确定阵列的来源,但是为了创建一个合适的凭证,你应该覆盖初始化方法,就像你在User
类中所做的那样:
class Voucher
def initialize(type, *attrs)
@type = type
# you should probably do something with attrs as well.
end
end
现在您可以调用Voucher.new
来构建初始化的凭证对象:
Voucher.new(:default).class #=> Voucher
如果你想保持相同的api,你可以按如下方式定义self.create:
class Voucher
def self.create(type, *attrs)
new(type, *attrs)
end
end
Voucher.create(:default, :some, :more, :attrs).class #=> Voucher
顺便说一句,你并不需要在User
类的初始化方法中检查nil,以下内容是等效的:
class User
def initialize(voucher = nil, orders =[])
@orders = orders
@voucher = voucher
end
end
查看您的测试,凭证的创建方法有两个参数,即凭证类型和属性哈希。
Voucher.create(:default, credit: 15, discount: 50)
相当于
Voucher.create(:default, { credit: 15, discount: 50 })
所以你可能想要定义凭证的初始化方法如下:
class Voucher
def initialize(type, attrs = {})
@type = type
# iterate through the attributes hash and assign attributes appropriately
end
end
假设您已为要分配的每个属性键定义了setter,您可以执行以下操作:
def initialize(type, attrs = {})
@type = type
attrs.each do |key, value|
send("#{key}=", value)
end
end
请参阅发送here的文档。
给出以下代码行:
Voucher.new(:default, credit: 15, discount: 50)
凭证的初始化功能会发生以下逻辑:
@type = :default
# iterate through the hash { credit: 15, discount: 50 }
self.credit=(15) # equivalent to self.credit = 15
self.discount=(50) # equivalent to self.discount = 50
然后您将使用正确初始化的凭证对象。
可以直接修改您的创建方法。