0

我有以下新的并创建按预期运行的操作(当我使用浏览器执行以下任务时,一切正常):

def new
  @user = User.find(params[:user_id])
  @profile = @user.build_profile
end

def create
  @user = User.find(params[:user_id])
  @profile = @user.build_profile(params[:profile])
  respond_to do |format|
    if @profile.save
      format.html { redirect_to user_dashboard_path(@user, @user.dashboard), notice: 'Profile was successfully created.' }
      format.json { render action: 'show', status: :created, location: @profile }
    else
      format.html { render action: 'new' }
      format.json { render json: @profile.errors, status: :unprocessable_entity }
    end
  end
end

但是,我不明白如何使用我的工厂为创建操作编写干净的 rspec 测试。

我有以下有效的测试:

before(:each) do
  @user = FactoryGirl.create(:admin)
  sign_in @user
end

it "creates a new Profile" do
  @profile = User.find(@user.id).build_profile #because this typically happens before in my 'new' action

  expect {
    post :create, :user_id => @user.id, :profile => {"first_name"=>"string",
     "middle_name"=>"string",
     "last_name"=>"string",
     "phone_number"=>"3213213211",
     "birth_date(1i)"=>"2013",
     "birth_date(2i)"=>"7",
     "birth_date(3i)"=>"4"}
  }.to change(Profile, :count)
end

使用它作为我的工厂:

FactoryGirl.define do
  factory :profile do
    first_name "MyString"
    middle_name "MyString"
    last_name "MyString"
    phone_number 2108545339
    birth_date Date.new(1987,8,11)
  end
end

但是我声明了post :create动作的所有参数,这很混乱。

似乎应该有一种方法可以让我传入工厂创建的对象而不是我的显式参数 - 但我不确定语法如何工作。

有小费吗?

4

1 回答 1

0

我不确定上述@profile = ...声明的目的,尽管有评论,因为您没有在测试中使用结果。

无论如何,如果不是因为您的参数需要单独的出生日期字段,您可以创建/使用Profile工厂来创建配置文件对象,然后使用.attributes.slice(:first_name, :middle_name, ...或从创建的配置文件中提取您需要的属性.attributes.except(:id, ...)

但是,鉴于这三个单独的出生日期字段,如果您想通过 创建参数FactoryGirl,则必须定义一个单独的类,如

class ProfileParameters
  attr_accessor :first_name, :middle_name, ..., :"birth_date(1i)", ...
end

使用适当的参数值创建工厂后,您可以传入 FactoryGirl.create(:profileParameters) for theprofile parameter in yourpost` 调用。

于 2013-07-05T21:24:30.810 回答