0
votes

Capybara is giving me the NoElementFound errors in my test my test

Describe "agenda pages" do
    subject { page }

    login_user

    describe "Agenda Creation" do
        before { visit users_path }

        describe "with invalid information" do
            it "should not create an agenda" do
                expect { click_button "Post" }.should_not change(Agenda, :count)
            end
            describe "error message" do
                before  { click_button "Post" }
                it { should have_content('error') }
            end
        end

        describe "with valid information" do
            before  { fill_in 'agenda_subject', with: "Lorem Ipsum" }
            it "should create a an agenda" do
                expect { click_button "Post" }.should change(Agenda, :count).by(1)
            end
        end

    end

end

My suspicion is capybara is not finding the element because of my visit users_path, its just not seeing the page. Note, behavoir is as expected in productivity and is working) I get same error if i change it to root_path. my spec_helper file has the url_helpers enabled and the form is correct with correct values. At least I"m sure, the form is at the end of the post my routes

   root        /                              users#index
                    root        /                              home#index
        new_user_session GET    /users/sign_in(.:format)       devise/sessions#new
            user_session POST   /users/sign_in(.:format)       devise/sessions#create
    destroy_user_session DELETE /users/sign_out(.:format)      devise/sessions#destroy
           user_password POST   /users/password(.:format)      devise/passwords#create
       new_user_password GET    /users/password/new(.:format)  devise/passwords#new
      edit_user_password GET    /users/password/edit(.:format) devise/passwords#edit
                         PUT    /users/password(.:format)      devise/passwords#update
cancel_user_registration GET    /users/cancel(.:format)        devise/registrations#cancel
       user_registration POST   /users(.:format)               devise/registrations#create
   new_user_registration GET    /users/sign_up(.:format)       devise/registrations#new
  edit_user_registration GET    /users/edit(.:format)          devise/registrations#edit
                         PUT    /users(.:format)               devise/registrations#update
                         DELETE /users(.:format)               devise/registrations#destroy
                   users GET    /users(.:format)               users#index
                 agendas POST   /agendas(.:format)             agendas#create
                  agenda DELETE /agendas/:id(.:format)         agendas#destroy

routes file

Engage::Application.routes.draw do
  authenticated :user do
    root to: 'users#index'
  end
  root :to => "home#index"
  devise_for :users
  resources :users, only: [:index]
  resources :agendas, only: [:create, :destroy]
end

I'm using spec and devise. Here is the rendered form:

<%= form_for(@agenda) do |f| %>
  <div class="field">
    <%= f.text_area :subject, placeholder: "Compose new agenda..." %>
  </div>
  <%= f.submit "Post", class: "btn btn-large btn-primary" %>
<% end %>
1
Is this a controller test or an integration test? - DVG
Updated my answer below. - DVG

1 Answers

0
votes

So, for a controller test, you really shouldn't be using capybara. Capybara is an integration testing library for driving a browser. To test the controller directly, you'll set up a request and post/get/put/etc to the action in question and verify you get what you expect out of the action. Often this will be verify a record was created or examining the contents of the instance variable.

Your controller does not know about routing. The point of a unit test is to test it isolated from these other components. To test it all together with Capybara, make a integration test. (Integration = more than one thing at a time!)

For example:

expect { post :create, agenda: FactoryGirl.attributes_for(:agenda)}.to change(Agenda, :count).by(1)

agenda = FactoryGirl.create(:agenda)
get :show, id: agenda
assigns(:agenda).should eq agenda