简体   繁体   English

Rspec使用from来测试控制器?

[英]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". 测试错误显示“预期结果已从0更改为1,但未更改”。 Is this a factory issue or rspec issue? 这是工厂问题还是rspec问题? 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: 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. 根据Fab的要求,这是我目前正在解决此问题的方式。

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. 在这里,我叫user2.reload以便从user2工厂获取更新的属性。

I don't know why the expect{} syntax doesn't work for factories but you could refactor your code like this: 我不知道为什么expect{}语法不适用于工厂,但是您可以像这样重构代码:

  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. 同样,我并不是说这是最佳实践,我只是在FactoryGirl文档中找不到有关RSpec 3的任何信息,这些信息都期望控制器中更新属性的语法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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