1

次のようなテストがあります。

test "should get create" do
   current_user = FactoryGirl.build(:user, email: 'not_saved_email@example.com')
   assert_difference('Inquiry.count') do
     post :create, FactoryGirl.build(:inquiry)
    end
    assert_not_nil assigns(:inquiry)
    assert_response :redirect
end

これは、コントローラーのこの部分をテストしています。

def create
    @inquiry = Inquiry.new(params[:inquiry])
    @inquiry.user_id = current_user.id
    if @inquiry.save
      flash[:success] = "Inquiry Saved"
      redirect_to root_path
    else
      render 'new'
    end
  end

そして工場:

FactoryGirl.define do

  factory :inquiry do
    product_id 2
    description 'I have a question about....'
  end
end

しかし、テストでエラーが発生し続けます:

      1) Error:
test_should_get_create(InquiriesControllerTest):
RuntimeError: Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id

私は何を間違っていますか?私は current_user を設定する必要があり、私はテストに参加していると信じていますが、明らかに、それは機能していません。

4

2 に答える 2

3

を作成していませんcurrent_usertestブロックでのみ初期化されました。それを行うには、次の 2 つの異なる方法があります。

まず、devise テスト ヘルパーを使用します。そんな感じ

let(:curr_user) { FactoryGirl.create(:user, ...attrs...) }
sign_in curr_user

考案ドキュメント

current_user次に、テスト環境のコントローラーでメソッドをスタブできます

controller.stub(current_user: FactroryGirl.create(:user, ...attrs...))

FactoryGirld.create(...)また、ファクトリ オブジェクトを永続化する必要があるため、代わりにを使用する必要がありFactoryGirl.build(...)ます (db に保存され、idnil 以外の属性があります) 。

于 2012-08-20T15:39:32.513 に答える
1

頭に浮かぶことがいくつかあります:

FactoryGirl.build(:user, ...)ユーザーの保存されていないインスタンスを返します。Factory.create保存されていないインスタンスには存在せずid、(通常はセッションベースの)current_userゲッターがデータベースからロードする方法がないため、代わりに使用することをお勧めします。Devise を使用している場合は、作成後にユーザーを「サインイン」する必要があります。これには、DB にレコードを保存し、それへの参照をセッションに入れることが含まれます。デバイスウィキを参照してください

また、このように ActiveRecord オブジェクトをcreateアクションに渡すのは、私には奇妙に見えます。

post :create, FactoryGirl.build(:inquiry)

たぶん、あなたの意図を認識するいくつかのレールマジックが働いているかもしれませんが、明示的に行うことをお勧めします:

post :create, :inquiry => FactoryGirl.build(:inquiry).attributes

または、さらに良いことに、工場から切り離します (テスト コードの DRY および美的原則は、アプリケーション コードとは異なります)。

post :create, :inquiry => {product_id: '2', description: 'I have a question about....'}

これは id = 2 の製品を参照します。DB に FK 参照制約がない場合を除き、アクションが発生する前に製品インスタンスが DB に存在する必要がある場合があります。

于 2012-08-20T15:24:37.803 に答える