Forum: RSpec RSpec - Testing ActiveRecord addins

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
171ea139761951336b844e708d1547ab?d=identicon&s=25 James Byrne (byrnejb)
on 2009-01-29 22:54
(Received via mailing list)
I wish to test a small library that I have written.  The module
resides in a file in ./lib.  It is loaded in the application via a a
file in ./config/initializers that contains the following code:

> require 'hll_audit_stamps'
> ActiveRecord::Base
>  include ActiveRecord::HLLAuditStamps
> end

My questions are really procedural in nature.  What do I put at the
top of my spec file to load an ActiveRecord instance containing the
custom module? Or, do I put the code given above into
spec_helper.rb?

I am really only interested in the actions of the module so I would
like to create a test model instance (Mytable) inside the spec
rather than create a dummy model in app/models.  How do you do this
without connecting to an underlying database?  I am unfamiliar with
mocks, although this seems to be the case for one.  Nonetheless, am
am uncertain how a mock would inherit the necessary characteristics
from the module that I am testing?

I would appreciate guidance here.

Sincerely,




--
***          E-Mail is NOT a SECURE channel          ***
James B. Byrne                mailto:ByrneJB@Harte-Lyne.ca
Harte & Lyne Limited          http://www.harte-lyne.ca
9 Brockley Drive              vox: +1 905 561 1241
Hamilton, Ontario             fax: +1 905 561 0757
Canada  L8E 3C3
C694a032be7518a0d704318895f8fe1d?d=identicon&s=25 Ben Mabey (mabes)
on 2009-01-29 23:19
(Received via mailing list)
James B. Byrne wrote:
>
> am uncertain how a mock would inherit the necessary characteristics
> from the module that I am testing?
>
> I would appreciate guidance here.
>
> Sincerely,
>
>
>
>
>
Hi James,
 From the looks of it you may want to move your module into a plugin and
then have it's own set of specs.  Doing this may make your life easier
in running specs in the fashion you are wanting to.  In the past I have
done just this and have used the in-memory sqlite3 adapter with some
dummy AR classes, just as you have explained.  In your plugin's
spec_helper put something like this:

ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :dbfile
=> ":memory:")

def setup_db
  ActiveRecord::Schema.define(:version => 1) do
    create_table :vehicles do |t|
      t.string :type, :name
      t.integer :dealership_id
    end
    create_table :dealerships do |t|
      t.string :name
    end
  end
end

def teardown_db
  ActiveRecord::Base.connection.tables.each do |table|
    ActiveRecord::Base.connection.drop_table(table)
  end
end

setup_db

class Vehicle < ActiveRecord::Base
...
end

class Dealership < ActiveRecord::Base
...
end



You can then use the dummy AR classes in your specs with an in-memory
DB.

I hope that helps,

Ben
171ea139761951336b844e708d1547ab?d=identicon&s=25 James Byrne (byrnejb)
on 2009-01-30 00:37
Ben Mabey wrote:

>
> You can then use the dummy AR classes in your specs with an in-memory
> DB.
>
> I hope that helps,
>
> Ben

Oh, yes. very much. Especially this example.

> def setup_db
>   ActiveRecord::Schema.define(:version => 1) do

Have you, or anyone reading this, had any experience with the nulldb gem
as an alternative to in memory sqlite3?
C694a032be7518a0d704318895f8fe1d?d=identicon&s=25 Ben Mabey (mabes)
on 2009-01-30 04:47
(Received via mailing list)
James Byrne wrote:
>
> Oh, yes. very much. Especially this example.
>
>
>> def setup_db
>>   ActiveRecord::Schema.define(:version => 1) do
>>
>
> Have you, or anyone reading this, had any experience with the nulldb gem
> as an alternative to in memory sqlite3?
>
I used nulldb on my last project and I had a lot of success with it.
Using nulldb comes with tradeoffs though and in this case I would just
use sqlite.  Unless the project and spec suite is large disconnecting
the DB may not be worth the effort.

-Ben
3399cbfb9e5fec93c324789b29309911?d=identicon&s=25 Pat Nakajima (patnakajima)
on 2009-01-30 07:10
(Received via mailing list)
(Sorry if this is double-posted, I was having trouble with joining the
list)

If you want an easy way to test ActiveRecord extensions, check out
acts_as_fu: http://github.com/nakajima/acts_as_fu. It makes generating
ActiveRecord models dead simple.

Pat
C694a032be7518a0d704318895f8fe1d?d=identicon&s=25 Ben Mabey (mabes)
on 2009-01-30 07:27
(Received via mailing list)
Pat Nakajima wrote:
> (Sorry if this is double-posted, I was having trouble with joining the
> list)
>
> If you want an easy way to test ActiveRecord extensions, check out
> acts_as_fu: http://github.com/nakajima/acts_as_fu. It makes generating
> ActiveRecord models dead simple.
>
> Pat
>

Very slick.  I'll be using this next time. :)

-Ben
171ea139761951336b844e708d1547ab?d=identicon&s=25 James Byrne (byrnejb)
on 2009-01-30 15:25
Pat Nakajima wrote:
> (Sorry if this is double-posted, I was having trouble with joining the
> list)
>
> If you want an easy way to test ActiveRecord extensions, check out
> acts_as_fu: http://github.com/nakajima/acts_as_fu. It makes generating
> ActiveRecord models dead simple.
>
> Pat

This seems to be just what the behaviourist ordered...  I am going to
try this out for my present situation.
171ea139761951336b844e708d1547ab?d=identicon&s=25 James Byrne (byrnejb)
on 2009-01-30 17:10
Pat Nakajima wrote:

> If you want an easy way to test ActiveRecord extensions, check out
> acts_as_fu: http://github.com/nakajima/acts_as_fu. It makes generating
> ActiveRecord models dead simple.
>

This seems to work very well.  However, I am causing myself a problem
with the logger and I could use some clarification on what is happening
so that I can fix it.

I created a custom logger to format the log output into syslog style.
So, in environment.rb I have this:

  # Customize logger - 'require "syslog_formatter"'
  config.logger = RAILS_DEFAULT_LOGGER = Logger.new(config.log_path)
  config.logger.formatter = SyslogFormatter.new
  config.logger.level     = Logger::INFO # DEBUG, WARN, ERROR, FATAL

and lib/syslog_formatter.rb has this:

# Configure custom logger used in all environments

class SyslogFormatter
  def call(level, time, program, message)
    l_time    = time.strftime("%b %d %H:%M:%S")
    l_process = "rails[#{$PID}]"
    l_host    = Socket.gethostname.split('.')[0]
    l_user    = @current_user if defined?(@current_user)
    l_text    = (String === message ?  message :
message.inspect).gsub(/\n/, '').strip
    "#{l_time} #{l_host} #{l_process} #{l_text} #{l_user}\n"
  end
end

and when I run rake spec I see this:

NameError in 'Role should create a new instance given valid attributes'
undefined local variable or method `logger' for
#<Spec::Rails::Example::ModelExampleGroup::Subclass_4:0x2ad081fa0998>
/usr/lib64/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_controller/test_process.rb:471:in
`method_missing'
/home/byrnejb/Software/Development/Projects/proforma.git/spec/spec_helper.rb:25:

Which is explicitly related to this code in spec_helper.rb:

# Custom Logger

  config.before(:each) do
    full_example_description = "#{self.class.description}
#{@method_name}"
    logger.info(
      "\n\n#{full_example_description}\n#{'-' *
          (full_example_description.length)}")
  end

Do I just comment this out or is there something else I should do, short
of disabling my own custom logger, to get this to work?
171ea139761951336b844e708d1547ab?d=identicon&s=25 James Byrne (byrnejb)
on 2009-01-30 17:32
James Byrne wrote:

>
> and when I run rake spec I see this:
>
> NameError in 'Role should create a new instance given valid attributes'
> undefined local variable or method `logger' for
> #<Spec::Rails::Example::ModelExampleGroup::Subclass_4:0x2ad081fa0998>
> 
/usr/lib64/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_controller/test_process.rb:471:in
> `method_missing'
> /home/byrnejb/Software/Development/Projects/proforma.git/spec/spec_helper.rb:25:
>
> Which is explicitly related to this code in spec_helper.rb:
>
> # Custom Logger
>
>   config.before(:each) do
>     full_example_description = "#{self.class.description}
> #{@method_name}"
>     logger.info(
>       "\n\n#{full_example_description}\n#{'-' *
>           (full_example_description.length)}")
>   end
>

If I comment out my own custom logger in environment.rb this error
remains nonetheless.  I have not run spec before this in this project so
I have no baseline to work from.
171ea139761951336b844e708d1547ab?d=identicon&s=25 James Byrne (byrnejb)
on 2009-01-30 17:52
Pat Nakajima wrote:

> If you want an easy way to test ActiveRecord extensions, check out
> acts_as_fu: http://github.com/nakajima/acts_as_fu. It makes generating
> ActiveRecord models dead simple.

Perhaps I misunderstood what this gem is supposed to provide but when I
call create! on an object produced by ActsASFu::build_model then I get a
method missing error.  If I call create instead then I get a private
method exception. Since what I am testing is a library that links into
the create method this behaviour is problematic.

Other than this show stopper (for this situation) the gem seems to be
quite user/tester friendly and useful.
3399cbfb9e5fec93c324789b29309911?d=identicon&s=25 Pat Nakajima (patnakajima)
on 2009-01-30 18:06
(Received via mailing list)
So, in acts_as_fu, I actually set the ActiveRecord logger to just log
to a StringIO that you can inspect by calling ActsAsFu.log. That's not
going to fly for your project though, so let me give the ability to
set your own. It'll be committed soon.

- Pat
3399cbfb9e5fec93c324789b29309911?d=identicon&s=25 Pat Nakajima (patnakajima)
on 2009-01-30 18:19
(Received via mailing list)
James,

Can you show me how you're trying to use ActsAsFu?

Pat
3399cbfb9e5fec93c324789b29309911?d=identicon&s=25 Pat Nakajima (patnakajima)
on 2009-01-30 18:19
(Received via mailing list)
After taking another look, I think you may be able to do something
like this to test your logger:
https://gist.github.com/3c55cbec990f283c5399

Let me know if that works.

Pat
171ea139761951336b844e708d1547ab?d=identicon&s=25 James Byrne (byrnejb)
on 2009-01-30 19:09
Pat Nakajima wrote:
> James,
>
> Can you show me how you're trying to use ActsAsFu?
>
> Pat

Not easily, because I removed the code.  When I get a moment I will
reset it and post here.  It will be later today.
171ea139761951336b844e708d1547ab?d=identicon&s=25 James Byrne (byrnejb)
on 2009-01-30 19:12
Pat Nakajima wrote:
> After taking another look, I think you may be able to do something
> like this to test your logger:
> https://gist.github.com/3c55cbec990f283c5399

I am not trying to test my custom logger.  That part has worked for a
few weeks now.

What is happening is that RSpec is blowing up at its own logger code in
the default spec_helper.rb file. This happens whether or not ActAsFu is
installed and whether or not my custom logger is commented out in
environment.rb
171ea139761951336b844e708d1547ab?d=identicon&s=25 James Byrne (byrnejb)
on 2009-01-30 21:24
James Byrne wrote:
> Pat Nakajima wrote:
>> James,
>>
>> Can you show me how you're trying to use ActsAsFu?
>>
>> Pat
>
> Not easily, because I removed the code.  When I get a moment I will
> reset it and post here.  It will be later today.

Here is what I have.  FYI once I removed the custom logger from
spec_helper.rb everything worked just fine thereafter.

# hll_audit_stamps_spec.rb
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')

describe "Builds a Model with custom magic columns" do
  before(:all) do
    build_model   :magiks do
      string    :description
    # these are Rails' own magic columns
      datetime  :created_at
      datetime  :created_on
      datetime  :updated_at
      datetime  :updated_on
    # these are our custom magic columns
      ActiveRecord::Base::HLL_AUDIT_COLUMNS.each do |magic_column|
        string    magic_column  if /.*_by\z/.match(magic_column)
        datetime  magic_column  if /.*_(at|on)\z/.match(magic_column)
      end
    end
    @my_mage = Magik.new
    @my_mage.save!
  end

# control - make sure the default behaviour is preserved
  it "should set Rails created_at" do
    @my_mage.created_at.should_not be_nil
    puts @my_mage.created_at
  end

  it "should set Rails created_on" do
    @my_mage.created_on.should_not be_nil
    puts @my_mage.created_on
  end
...
3399cbfb9e5fec93c324789b29309911?d=identicon&s=25 Pat Nakajima (patnakajima)
on 2009-01-30 22:42
(Received via mailing list)
Glad it works. Just so you know, you can get created_at and updated_at
by calling #timestamps:

    require 'rubygems'
    require 'acts_as_fu'
    require 'spec'

    describe "timestamps" do
      before(:each) do
        build_model(:people) { timestamps }
        @person = Person.create!
      end

      it "adds created_at" do
        @person.created_at.should_not be_nil
      end

      it "adds updated_at" do
        @person.updated_at.should_not be_nil
      end
    end

Pat
171ea139761951336b844e708d1547ab?d=identicon&s=25 James Byrne (byrnejb)
on 2009-02-02 19:49
James Byrne wrote:

>
> What is happening is that RSpec is blowing up at its own logger code in
> the default spec_helper.rb file. This happens whether or not ActAsFu is
> installed and whether or not my custom logger is commented out in
> environment.rb

I poked at this a bit and hit upon the problem. As distributed,
spec_helper.rb says this:

  config.before(:each) do
    full_example_description = "#{self.class.description}
#{@method_name}"
    logger.info(
      "\n\n#{full_example_description}\n#{'-' *
          (full_example_description.length)}")
  end

The fix is to prefix logger with Rails:: thus:

  config.before(:each) do
    full_example_description = "#{self.class.description}
#{@method_name}"
    Rails::logger.info(
      "\n\n#{full_example_description}\n#{'-' *
          (full_example_description.length)}")
  end

I have one other difficulty when running this on MS-WinXPpro under
cygwin. The newline character seems to have no effect.  I can force it
to behave locally by adding a \r in front of each \n but, obviously,
that will have unfortunate consequences on *nix.

Suggestions welcome.
171ea139761951336b844e708d1547ab?d=identicon&s=25 James Byrne (byrnejb)
on 2009-02-02 20:12
James Byrne wrote:

>
> I have one other difficulty when running this on MS-WinXPpro under
> cygwin. The newline character seems to have no effect.  I can force it
> to behave locally by adding a \r in front of each \n but, obviously,
> that will have unfortunate consequences on *nix.

Actually, that technique does not seem to work either. A ^M is inserted
into the og file, but it has no evident effect.
This topic is locked and can not be replied to.