0

I am trying to write my first tests and I am using rspec and FactoryGirl to do so. However I stumbled a bit validating a model(even though the validations are very basic). I have writen a test without FactoryGirl and with FactoryGirl mainly:

require "rails_helper"


describe Picture do

    context 'validates picture model' do

        it 'fails validation if no picture is present' do
            pic = Picture.create(title: "titlu", description: "Descriere", category_id: 1,
                                  photo: nil)
            expect(pic.errors[:photo].size).to eq(1)
        end

    end
end

This works as intended and the test passes. I tried using FactoryGirl with the method .build to create the object(otherwise FactoryGirl has no purpose if for every object I have to write it by hand). This is my attempt:

require "rails_helper"


describe Picture do

    context 'validates picture model' do

        it 'fails validation if no picture is present' do
            pic = FactoryGirl.build(:picture)
            pic.photo = nil
            pic.save
            expect(pic.errors[:photo].size).to eq(1)
        end

    end
end  

However this test fails. This is my factories.rb file:

FactoryGirl.define do
    factory :category do |f|
        f.sequence(:name) { |n| "foo#{n}" }
    end

    factory :picture do |f|
        f.title "PozaDinFactory"
        f.description "DescriereDinFactory"
        f.association :category_id, factory: :category
        f.photo { File.new("#{Rails.root}/spec/support/index.jpeg") } 
    end

    factory :comment do |f|
        f.text "Un comentariu din factory Girl"
        f.association :picture_id, factory: :picture
        f.user_id 1
    end

    factory :user do
    email { Faker::Internet.email }
    password "password"
    password_confirmation "password"
  end
end  

What is the difference between the 2 tests ? Since the first without factory passes and the one with factory fails(no errors are found in the photo field).
O and this is my picture model:

class Picture < ActiveRecord::Base
    belongs_to :category, counter_cache: true
    has_many :comments, dependent: :destroy
    mount_uploader :photo, PhotoUploader
    validates_presence_of :photo
    validates :title, presence: true
end  

Any suplimentary tips on testing, code writing and so on are appreciated :D P.S. I have done this to other fields in picture like Title or Description and the test pass with both factorygirl and the Picture.create methods. The field photo since it refers to an uploader might have something different ...

Lucian Tarna
  • 1,806
  • 4
  • 25
  • 48

1 Answers1

1

Could it be, that the test fails with an exception? Something like No such file or directory?

If so you can have a look at this answer. It adresses Paperclip file uploads but as the fixture_file_upload is a rails method it should work with other uploads as well.

So you can try this:

f.photo { fixture_file_upload("#{Rails.root}/spec/support/index.jpeg") } 

Another thing are traits, which in your case are much cleaner (and sometimes work better) with factory girl.

Example:

factory :picture do
  title "PozaDinFactory"
  description "DescriereDinFactory"
  association :category_id, factory: :category
  photo { File.new("#{Rails.root}/spec/support/index.jpeg") } 

  trait :without_photo do
    photo nil
  end    
end

And you call it with:

FactoryGirl.build(:picture, :without_photo)
Community
  • 1
  • 1
smallbutton
  • 3,377
  • 15
  • 27
  • That trait is magic.. it did the job. I didn't add fixture_file_upload. So odd that it worked with just the trait. Thank you very much! – Lucian Tarna Aug 05 '15 at 09:24