简体   繁体   中英

Rspec testing a controller using from to?

Tested in browser and works fine. Test error says "expected result to have changed from 0 to 1, but did not change". Is this a factory issue or rspec issue? Why is it not changing?

Error:

Failures:

  1) ShortLinksController Short links controller Clicking a short link increments the click counter by 1
     Failure/Error: expect{ get :url_dispatch, { id: short_link.short_link } }.to change{short_link.click_counter}.from(0).to(1)
       expected result to have changed from 0 to 1, but did not change
     # ./spec/controllers/short_links_controller_spec.rb:34:in `block (4 levels) in <top (required)>'

Rspec:

  it "increments the click counter by 1" do
    short_link = create(:short_link)
    expect{ get :url_dispatch, { id: short_link.short_link } }.to change{short_link.click_counter}.from(0).to(1)
  end

Controller:

  def url_dispatch
    id = params[:id]
    record = ShortLink.where(["short_link = ?", id]).first

    if record.update(click_counter: record.click_counter + 1)
      redirect_to record.redirect_to
    else
      render '/not_found'
    end
  end

Factory:

FactoryGirl.define do
  factory :short_link do
    redirect_to "http://google.com"
    title "This is the google page"
    short_link "xGh7u"
    click_counter 0
    owner Owner.create!(first_name: "Bob", last_name: "Diller", email: "bdiller@example.com")
  end
end

per Fab's request, here is how I'm currently working around the issue.

context 'save invocations' do
  before(:each) do
    @org = create(:organization)
    user = create(:user, organization: @org, is_admin: true)
    sign_in user
  end
  it 'valid scenario' do
    user2 = create(:user, organization: @org, is_admin: false)
    put :update, id: user2, user: { is_admin: true }

    user2.reload
    expect(response).to have_http_status(204)
    expect(user2.is_admin).to eq true
  end
end

Here I'm calling user2.reload in order to get the updated attributes from the user2 factory.

I don't know why the expect{} syntax doesn't work for factories but you could refactor your code like this:

  it "increments the click counter by 1" do
    short_link = create(:short_link)
    count = short_link.click_counter
    get :url_dispatch, { id: short_link.short_link }
    short_link.reload

    expect(short_link.click_counter).to eq count + 1
  end

Again I'm not saying this is best practice, I just couldn't find anything in the FactoryGirl documentation regarding RSpec 3 expect syntax in controllers that update attributes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM