2012-02-19 110 views
1

说例如我在我的Rails应用程序中有两个类 - Customer类和一个Card类。客户类由一个卡类组成,即客户拥有一张卡。如何使用RSpec测试组合对象属性的设置?

然后我有一个定义了'do_something'动作的Rails控制器,它将使用传递给POST的参数初始化Customer的新实例(反过来将在内部创建一个新的Card实例)。

卡的数量则设置如下:

class ShopController < ApplicationController 
    def do_something 
     customer = Customer.new params 
     customer.card.number = params[:card_number] 
     ... 
    end 
end 

如何卡号的这种分配在一个RSpec测试测试?理想情况下,如果'should_receive_chain'存在,我们可以写:

describe MyController do 
    describe "POST 'do_something'" do 
     it "should set card number" 
      params = { :card_number => '1234' } 
      card_mock.should_receive_chain(:card, :number).with '1234' 
      post :do_something 
     end 
    end 
end 

任何想法?也许它不能被轻松测试的事实是代码味道,也许我应该在Customer类中创建一个setter方法?

回答

0

我认为你正在测试这个错误的水平。如果您想在单独的语句中设置卡号,那么创建一个函数来帮助完成此操作可能会更好。

class Customer 
    def self.new_with_card_number(params, number) 
    customer = new(params) 
    customer.card.number = number 
    customer 
    end 
end 

describe Customer do 
    it 'creates a card with a number' do 
    customer = described_class.new_with_card_number({}, '1234') 
    customer.card.number.should == '1234' 
    end 
end 

然后,您可以将您的控制器更改为:

class ShopController < ApplicationController 
    def do_something 
    customer = Customer.new_with_card_number(params, params[:card_number]) 
    end 
end 

一个简单的解决方案可能是简单地命名在表单中的参数,以便设置卡号是自动完成的:

params[:customer][:card_attributes][:card_number] 

然后,您可以将呼叫更改为customer = Customer.new(params)

0

我会改变客户模型添加accepted_nested_attributes_for :card和更改控制器动作

class ShopController < ApplicationController 
    def do_something 
    customer = Customer.create params[:customer] 
    ... 
    end 
end 

那么你的天赋可以像

describe ShopController do 
    describe 'POST /do_something' do 
    it "sets the card's card number" do 
     post :do_something, :customer => 
           { 
           :card_attributes => {:card_number => '1234'} 
           } 
     Customer.last.card.number.should == '1234' 
    end 
    end 
end