比如说我在我的Rails应用程序中有两个类 - Customer类和Card类。 Customer类由Card类组成,即客户有卡。
然后我有一个定义了'do_something'动作的Rails控制器,它将使用在POST上传入的参数初始化一个新的Customer实例(反过来将在内部创建一个新的Card实例)。 p>
然后将卡的编号设置如下:
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 :(得分: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)
。
答案 1 :(得分:0)
我会更改Customer模型以添加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