Search code examples
ruby-on-railsrubyruby-on-rails-4rspecrspec-rails

Weird behaviour from Rspec Rails (Different outputs for the same test )


I'm experiencing a very weird behaviour with my Rspec tests.

I have the following test to demonstrate the problem:

require 'spec_helper'

describe "RESTful API" do

  describe "Listing Entities" do

    context 'With valid Token' do

      before do
        entries = create_list(:entry, 10)
        admin   = create(:admin) 
        get api_entries_path, {token: admin.api_key.token}        
      end


      it 'Shows a list of entries' do     
        puts JSON.parse(response.body)
      end

      it "Should show no entries when the user has no data" do          
        puts JSON.parse(response.body) 
      end

    end

  end
end

The very weird behaviour is that I'm getting two different outputs while I'm supposed to have the exact same response. I'm getting the followings:

{"entries"=>[{"id"=>1, "user_id"=>1, "username"=>"admin", "distance"=>50.0, "time_period"=>60, "date_time"=>"2014-05-15 03:36:11 +0300", "created_at"=>"2014-05-15T01:54:40.000Z", "distance_type"=>"Km"}, {"id"=>2, "user_id"=>1, "username"=>"admin", "distance"=>50.0, "time_period"=>60, "date_time"=>"2014-05-15 03:36:11 +0300", "created_at"=>"2014-05-15T01:54:40.000Z", "distance_type"=>"Km"}, {"id"=>3, "user_id"=>1, "username"=>"admin", "distance"=>50.0, "time_period"=>60, "date_time"=>"2014-05-15 03:36:11 +0300", "created_at"=>"2014-05-15T01:54:40.000Z", "distance_type"=>"Km"}, {"id"=>4, "user_id"=>1, "username"=>"admin", "distance"=>50.0, "time_period"=>60, "date_time"=>"2014-05-15 03:36:11 +0300", "created_at"=>"2014-05-15T01:54:40.000Z", "distance_type"=>"Km"}, {"id"=>5, "user_id"=>1, "username"=>"admin", "distance"=>50.0, "time_period"=>60, "date_time"=>"2014-05-15 03:36:11 +0300", "created_at"=>"2014-05-15T01:54:40.000Z", "distance_type"=>"Km"}, {"id"=>6, "user_id"=>1, "username"=>"admin", "distance"=>50.0, "time_period"=>60, "date_time"=>"2014-05-15 03:36:11 +0300", "created_at"=>"2014-05-15T01:54:40.000Z", "distance_type"=>"Km"}, {"id"=>7, "user_id"=>1, "username"=>"admin", "distance"=>50.0, "time_period"=>60, "date_time"=>"2014-05-15 03:36:11 +0300", "created_at"=>"2014-05-15T01:54:40.000Z", "distance_type"=>"Km"}, {"id"=>8, "user_id"=>1, "username"=>"admin", "distance"=>50.0, "time_period"=>60, "date_time"=>"2014-05-15 03:36:11 +0300", "created_at"=>"2014-05-15T01:54:40.000Z", "distance_type"=>"Km"}, {"id"=>9, "user_id"=>1, "username"=>"admin", "distance"=>50.0, "time_period"=>60, "date_time"=>"2014-05-15 03:36:11 +0300", "created_at"=>"2014-05-15T01:54:40.000Z", "distance_type"=>"Km"}, {"id"=>10, "user_id"=>1, "username"=>"admin", "distance"=>50.0, "time_period"=>60, "date_time"=>"2014-05-15 03:36:11 +0300", "created_at"=>"2014-05-15T01:54:40.000Z", "distance_type"=>"Km"}], "total_count"=>10}

{"entries"=>[], "total_count"=>0}

As you can see I got two different outputs.

As for the User and ApiKey models:

# Controller 

class Api::V1::EntriesController < Api::V1::BaseController

  def index
    @entries = @current_user.entries    
  end

end


class User < ActiveRecord::Base

  # relationships 
  has_many :entries
  has_one :api_key, dependent: :destroy

  # Generate API Key to be useed with the API
  after_create :create_api_key

  private

  def create_api_key
    ApiKey.create!(:user_id => self.id)
  end  

end

class ApiKey < ActiveRecord::Base
    belongs_to :user

    before_create :generate_token

    private

    def generate_token
      begin
        self.token = SecureRandom.hex.to_s
      end while self.class.exists?(token: token)
    end 
end

Please note that I have DatabaseCleaner as the following:

RSpec.configure do |config|

  config.before(:suite) do
    DatabaseCleaner.clean_with(:truncation)
  end

  config.before(:each) do
    DatabaseCleaner.strategy = :transaction
  end

  config.before(:each, :js => true) do
    DatabaseCleaner.strategy = :truncation
  end

  config.before(:each) do
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end

end

Please note that I'm using ruby(2.0), rails (4.0.4) and rspec-rails(2.14.2). I'm using OS X 10.7.

Any help would be appreciated.


Solution

  • After struggling for hours it turned out that I had to change:

    DatabaseCleaner.strategy = :transaction
    

    to :

    DatabaseCleaner.strategy = : truncation
    

    the truncation is resetting the id's back to 0 (well 1) where as transaction isn't, and I'm using a hard coded id in my factory.

    Thanks for your help Jon Rowe.