Bitwise
Bitwise

Reputation: 8461

RSpec Controller test, testing a post action

Right now I have a subscriber controller that creates a subscriber but that is not what I want to test. I also have a method in the controller that add 1 to the visit attribute on the Subscriber(I'll post the code) that is the method I want to test but I'm not sure how? I'm new to rails and Rspec so I'm having trouble grasping the concepts. I'll post my test and controller for clarity.

CONTROLLER:

def search
  @subscriber = Subscriber.new
end

def visit
  @subscriber = Subscriber.find_by_phone_number(params[:phone_number])
   if @subscriber
    @subscriber.visit =+ 1
    @subscriber.save
    flash[:notice] = "thanks"
    redirect_to subscribers_search_path(:subscriber)
  else
    render "search"
  end
end

TEST

it "adds 1 to the visit attribute" do
  sign_in(user)
  subscriber = FactoryGirl.create(:subscriber)
  visits_before = subscriber.visit
  post :create, phone_number: subscriber.phone_number
  subscriber.reload

  expect(subscriber.visit).to eq(visits_before)
end

ERROR MESSAGE:

enter image description here

As you can see that is the method I want to test. The current test in place does not work but I thought it might help to show what I'm thinking. Hopefully this is enough info, let me know if you want to see anything else?

Upvotes: 0

Views: 1617

Answers (3)

I think you could do something like this:

it 'adds 1 to the visit attribute' do
  # I'm assuming you need this, and you are creating the user before
  sign_in(user)
  # I'm assuming your factory is correct
  subscriber = FactoryGirl.create(:subscriber) 
  visits_before = subscriber.visit
  post :create, subscriber: { phone_number: subscriber.phone_number }
  subscriber.reload
  expect(subscriber.visit).to eq(visits_before)
end

Upvotes: 1

David Roberts
David Roberts

Reputation: 43

I think you're testing the wrong method. You've already stated that your create action works, so no need to test it here. Unit tests are all about isolating the method under test.

Your test as it is written is testing that post :create does something. If you want to test that your visit method does something, you'd need to do something like this:

describe "#GET visit" do
  before { allow(Subscriber).to receive(:find).and_return(subscriber) }
  let(:subscriber) { FactoryGirl.create(:subscriber) }

  it "adds one to the visit attribute" do
    sign_in(user)
    expect { get :visit }.to change(subscriber, :visit).by(1)
  end
end

Upvotes: 0

Alexander Kireyev
Alexander Kireyev

Reputation: 10825

Since you are checking subscriber.visits you should change Subscriber to subscriber:

expect { post :create, :subscriber => subscriber }.to change(subscriber, :visit).by(1)

visits is a method of an instance, not a class method.

Upvotes: 1

Related Questions