3

Am using twitter bootstrap gem to generate the views which displays the created_at column in the index page. The rspec tests which are generated along with the scaffolds use stub_model to test the index view. These test fails because created_at column in nil.

Just as stub_model generates as dummy id, can it also set the created_at column as Time.now. can that be done via config. or do we need to specify it each time while creating a stub.

Chris Salzberg
  • 27,099
  • 4
  • 75
  • 82
Kumaresan
  • 335
  • 3
  • 7

2 Answers2

6

Judging from the source code, this doesn't seem to be possible by default. This leaves you with a few options:

1. Specify the created_at value each time you create a model stub:

m = stub_model(MyModel, :created_at => Time.now)

2. Create your own helper method which sets the created_at attribute after initializing the stub:

module Helpers
  def stub_model_with_timestamp(model_class, stubs={})
    stub_model(model_class, { :created_at => Time.now }.merge(stubs))
  end
end

Then just include the module in spec_helper.rb so it is available in all specs:

RSpec.configure do |config|
  include Helpers
  ...
end

3. If you really want to use stub_method as-is, you could monkey-patch rspec-rails to make it work the way you want by re-opening the module and aliasing the original method:

module RSpec::Rails::Mocks
  def stub_model_with_timestamp(model_class, stubs={})
    stub_model_without_timestamp(model_class, { :created_at => Time.now }.merge(stubs))
  end

  alias_method_chain :stub_model, :timestamp
end 

Put this in a file in spec/support/ and it will load automatically, so when you stub a model it will automatically set the created_at timestamp.

As a final note, I think this is useful functionality that others might also want to use, so you might consider actually making a pull request to rspec-rails that adds the default setting as a config option. (I think if you do, you'd probably want to also set updated_at as well, for completeness.)

Hope that helps!

Chris Salzberg
  • 27,099
  • 4
  • 75
  • 82
  • I've updated the code to fix the issue pointed out by @kwerle. The timestamp is now merged into the `stubs` hash, so that other stubs can be passed in and there will not be a conflict. – Chris Salzberg Dec 14 '12 at 00:00
2

I added the following to my spec_helper.rb:

module RSpec::Rails::Mocks
  def stub_model_with_timestamp(*args)
    stub_model_without_timestamp(*args).tap{|o| o.created_at ||= Time.now }
  end

  alias_method_chain :stub_model, :timestamp
end

The other solution had trouble with "*args, :created_at => Time.now", as it adds an additional parameter to the stub call.

kwerle
  • 2,225
  • 22
  • 25
  • Thanks for pointing that out! I've updated my answer to fix this. My fix is a bit different from yours: I switch `*args` for `stub_model, stubs={}` and then merge the timestamp into `stubs`. This way it will not add an extra parameter. – Chris Salzberg Dec 14 '12 at 00:01