Search code examples
ruby-on-railstestingrspecdevise

An object instance not getting created in my test


The following is my test and everything works. The form gets filled with a name and image in the ui when I run the test. If I also test the presence of the user's name being created in the ui when I visit groups_path the test also passes. The only issue is that a group is not getting created. I'm not sure what I'm missing.

I'm using devise for authentication

create_group_spec.rb

require 'rails_helper'

RSpec.describe 'Creating a group', type: :feature do
  before :each do
    user = User.create!(name: 'Test user', email: 'test@gmail.com', password: '123456',
                       password_confirmation: '123456')
    login_as(user, scope: :user)
  end
  scenario 'adds a new group when name and image is entered' do
    visit new_group_path
    fill_in('Name', with: 'Sports')
    attach_file('Icon', "#{Rails.root}/integration_test_image/test.jpg")
    sleep(3)
    click_on 'Create Group'
    visit groups_path
    expect(page).to have_content('Sports')
  end
end

groups_controller.rb

  def create
    @group = Group.new(group_params)
    @group.user = current_user

    respond_to do |format|
      if @group.save
        format.html { redirect_to groups_url, notice: 'Group was successfully created.' }
        format.json { render :show, status: :created, location: @group }
      else
        format.html { render :new, status: :unprocessable_entity }
        format.json { render json: @group.errors, status: :unprocessable_entity }
      end
    end
  end

 private
  
  def group_params
    params.require(:group).permit(:name, :icon)
  end

Solution

  • No more sleeping on the job. sleep x doesn't actually guarentee that whatever your waiting for is actually finished - it just makes your tests slower and potentially flappy.

    require 'rails_helper'
    
    RSpec.describe 'Creating a group', type: :feature do
      before :each do
        # You should be using fixtures or factories instead.
        user = User.create!(name: 'Test user', email: 'test@gmail.com', password: '123456',
                           password_confirmation: '123456')
        login_as(user, scope: :user)
      end
      scenario 'adds a new group when name and image is entered' do
        visit new_group_path
        fill_in('Name', with: 'Sports')
        # use a block instead of sleep
        # images should also go in /spec/support or /spec/fixtures
        attach_file('Icon', Rails.root.join("/integration_test_image/test.jpg")) do
          click_on 'Create Group' # no need to visit since it will redirect
          expect(page).to have_content('Sports') # have_content waits for the page to load
        end
      end
    end