1

Here is my Rspec when testing an API end point related to Users:

 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

And the controller action that I am testing looks like this:

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

Surprisingly, the @user.inspect in the controller shows this:

"#<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\">"

And the user.inspect in the rspec, right after the call to the controller has been done, looks like this:

"#<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\">"

Why does the Rspec not catch the updates? I mean, I have tested this manually and the database gets updated correctly.

What am I missing here?

4

1 回答 1

3

In rspec example you define user method with let, which returns ActiveRecord object. Your controller is creating different object, that points to the same database entry. Change in db is not reflected in user object in rspec example, as there is no callback mechanism that would notify it to change.

Using #reload method on AR object in test should solve your problem, as it forces reloading data from db.

于 2013-06-22T11:40:55.800 回答