1

ユーザーに関連する API エンドポイントをテストするときの私の Rspec は次のとおりです。

 context "updating a user" do
    let(:user) { User.create! }

    it "should let me update a user without an email" do
      put "/api/v1/users/#{user.id}", {:user => {:first_name => 'Willy'}}.to_json, {'CONTENT_TYPE' => 'application/json', 'HTTP_AUTHORIZATION' => "Token token=\"#{auth_token.access_token}\""}
      p user.inspect
    end

そして、私がテストしているコントローラー アクションは次のようになります。

def update
    begin
      @user = User.find(params[:id])
      if @user.update_attributes(params[:user])
        p @user.inspect
        render json: @user, :except => [:created_at, :updated_at]
      else
        render json: { :errors => @user.errors }, :status => :unprocessable_entity
      end
    rescue ActiveRecord::RecordNotFound
      head :not_found
    end
  end

驚いたことに、コントローラーの @user.inspect はこれを示しています。

"#<User id: 2, first_name: \"Willy\", last_name: nil, email: nil, state: nil, created_at: \"2013-06-22 11:21:22\", updated_at: \"2013-06-22 11:21:22\">"

rspec の user.inspect は、コントローラーへの呼び出しが完了した直後に、次のようになります。

"#<User id: 2, first_name: nil, last_name: nil, email: nil, state: nil, created_at: \"2013-06-22 11:21:22\", updated_at: \"2013-06-22 11:21:22\">"

Rspec が更新をキャッチしないのはなぜですか? つまり、これを手動でテストしたところ、データベースが正しく更新されました。

ここで何が欠けていますか?

4

1 に答える 1

3

rspec の例では、 ActiveRecord オブジェクトを返す でuserメソッドを定義します。letコントローラーは、同じデータベース エントリを指す別のオブジェクトを作成しています。userrspec の例では、変更を通知するコールバック メカニズムがないため、db の変更は object に反映されません。

テストでARオブジェクトのメソッドを使用#reloadすると、dbからデータを強制的にリロードするため、問題が解決するはずです。

于 2013-06-22T11:40:55.800 に答える