0

私のテストは次のようになります。

def setup
    @period_registration= FactoryGirl.create(:period_registration)
  end


 test "should post save_period" do
    sign_in(FactoryGirl.create(:user))
     assert_difference('PeriodRegistration.count') do
      post :save_period, period_registration: FactoryGirl.attributes_for(:period_registration)
    end
    assert_not_nil assigns(:period_registration)

  end

しかし、実行すると、次のエラーが発生します。

 1) Error:
test_should_post_save_period(PeriodRegistrationsControllerTest):
NoMethodError: undefined method `event' for nil:NilClass

これが私のコントローラーです:

  def save_period
    @period_registration = PeriodRegistration.new(params[:registration])
    @period_registration.save
    flash[:success] = "Successfully Registered for Session."
    redirect_to event_url(@period_registration.period.event)
  end

私の工場は次のようになります。

factory :event do
    name 'First Event'
    street '123 street'
    city 'Chicago'
    state 'Iowa'
    date Date.today
  end


  factory :period do
    name 'First Period'
    description 'This is a description'
    start_time Time.now + 10.days
    end_time Time.now + 10.days + 2.hours
    event
    product
  end

factory :period_registration do
    user
    period
  end

期間オブジェクトとイベントオブジェクトを作成する必要がありますか?もしそうなら、どのように?いろいろな工場で「ピリオド」、「プロダクト」、「イベント」の順で自動的に作成されると思いますので、これは問題ではないと思います。

ここからどこを見ればいいのか、何かアイデアはありますか?

4

1 に答える 1

1

簡単な答え-はい、オブジェクトを作成します。

長い答え:

  1. コントローラー内:

    @period_registration.period.event
    

    このコード行は、デメテルの法則に違反しています。これは良いデザインではありません。このコード行は次のようになります。

    @period_registration.event
    

    ただし、PeriodRegistrationモデルで新しいメソッドを作成する必要があります。メソッドの最も単純な変形は次のとおりです。

    def event
      period.event
    end
    
  2. コントローラの場合:PeriodRegistrationモデルが保存されているかどうかはチェックされません。

  3. PeriodRegistrationモデルには2つの関連付けがあり、FactoryGirl.attributes_forを使用すると、ファクトリは関連付けられたオブジェクトを作成せず、PeriodRegistrationの属性のセットを提供するだけであることを理解しています。このテストに合格するには、コントローラーを呼び出す前に、これら2つのオブジェクトを作成する必要があります。また、ベストプラクティスは次のとおりです。テストにはアサーションを1つだけ含める必要があります。例えば:

    def setup
      @user = FactoryGirl.create(:user)
      @period = FactoryGirl.create(:period)
    end
    
    test "should post save_period" do
      sign_in(@user)
      assert_difference('PeriodRegistration.count') do
        post :save_period, period_registration: FactoryGirl.attributes_for(:period_registration, user: @user, period: @period)
      end
    end
    
    test "should assings @period_registration" do
      sign_in(@user)
      post :save_period, period_registration: FactoryGirl.attributes_for(:period_registration, user: @user, period: @period)
      assert_not_nil assigns(:period_registration)
    end
    
  4. コントローラをテストするときは、実際のモデルの代わりにモックオブジェクトを使用できます。

于 2012-09-01T01:28:24.287 に答える