2014-06-20 34 views
2

只是一個簡單的問題。我有一個測試規範,看起來是這樣的...爲什麼我的課程的一個實例被視爲一個數組?

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 

回答

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 

現在你可以調用如果你想保持相同的API

Voucher.new(:default).class #=> Voucher 

,那麼你可以定義self.create如下:Voucher.new建立一個初始化的對象券

class Voucher 
    def self.create(type, *attrs) 
    new(type, *attrs) 
    end 
end 

Voucher.create(:default, :some, :more, :attrs).class #=> Voucher 

順便說一句,你並不真正需要的是在你User類的初始化方法零檢查,以下是等價的:

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 

假設你已經定義的制定者爲每個被分配屬性鍵,您可以執行以下操作:

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 

,你風與正確初始化憑證的對象。

適當地修改您的創建方法非常簡單。

+0

嗨,感謝您的輸入。我無法改變測試規格,因爲它們是不可改變的例子的一部分。我必須使用憑證類的工廠方法模式。此外,我必須通過測試中的優惠券類。 – user3750194

+0

你介意擴展你正在展示的self.create嗎? 我得到我正在返回錯誤的信息,這應該已經像你所做的那樣創建了一個類的新實例。那麼我將如何去循環attrs數組並將它們分配給變量? – user3750194

+0

非常感謝你的擴展,這真的被清除了很多。 我想設置選項哈希變量現在,但我沒有得到任何東西。使用像你這樣的send方法拋出了一個未定義的方法錯誤。在做了一點研究之後,我實現了instance_variable_set方法,像 'instance_variable_set(「@#{subkey}」,subvalue)'這不會拋出任何錯誤,但是如果嘗試並調用變量集('@ credit','' self.credit','credit')在另一種方法中是空的。任何想法我在這裏做錯了嗎? – user3750194

相關問題