So, I am having some trouble running tests in Rails. When I ran 'Rake test' and I have something like this
http_basic_authenticate_with :name =>Hello.first.myhello, :password =>Hello.first.myhello
Inside my controller, I get an error
'method_missing': undefined method `myhello' for nil:NilClass (NoMethodError)
Clearly the fixtures aren't being loaded, is there anyway I can make them load and have this not fail? Using Rails 3.1.
** edit: possibly related SO question/answer? Basically, put this in your test unit class:
fixtures :hellos
If that doesn't do it, could you paste the relevant parts of your fixture and test class?
**original:
I'm not sure about your experience level or your setup, so just to confirm that you are testing what you think you are testing, could you add this line before the line in your question?
Hello.create(:name => some_value, :password => some_value)
In case there is any confusion,
undefined method `myhello' for nil:NilClass
indicates that you are not actually getting any records, not that you don't have the Hello model.
Related
I have this tiny bit of code, used in a few model classes in an application:
validates_format_of :month, :with => /\d{4}\/(0[1-9]|1[0-2])/i, :message => "must be in the format YYYY/MM"
What's the rails way to DRY this up? i.e., where should the code go and how should it be called?
take a look at Active Model Validator
You can use observer in rails
to DRY up your code.
This is maybe more of a philosophical question, but...
As I'm working with rspec and rails, I'm getting more comfortable with using mock objects and stubs to isolate my controller tests from my models, and vice versa.
However, that leaves me with a lingering feeling that not everything is connected properly.
As an example, I might have a spec for a controller like this:
it "passes a list of awesome cheeses to the view" do
Cheese.should_receive(:awesome).and_return( [ ] ) # one method name
get 'show'
assigns[:awesome_cheeses].should_not be_nil
end
And then a spec on my Cheese model like:
it "should return a list of awesome cheeses" do
Cheese.create!(:name => "American", :is_awesome => false)
Cheese.create!(:name => "Gouda", :is_awesome => true)
Cheese.awesome_cheeses.should_not be_nil # different method name!
end
If both those specs pass, my app will still be broken, because the method I stub out in the first spec doesn't have the same name as the one I make sure works in the second.
Now, one answer to this is "you need integration tests", but unless my integration tests are super thorough, I might miss an error like this one.
Is there any automated way to compare the methods I expect to be there in my controller tests, with the methods I actually test for in my model tests?
It now looks like there's an extension to Rspec called rspec-fire which claims to help with this. I haven't tried it yet but wanted to document it here for others.
I also want to link to this talk, because it has an awesome title: http://www.infoq.com/presentations/integration-tests-scam
I am using ruby on rails 3. I have a model called Content. Within the controller, I extract some variables and pass them to the Viewer. In the Viewer, I would like to use of my self made functions so that I don't have too much logic and code in the Viewer. I defined these functions in the ContentsHelper module.
My functions defined in the ContentsHelper module are making use of ActionViewer helper functions, however these are not available in the ContentsHelper module. I am getting for example NoMethodError: undefined method content_tag' for #<Content:0x1025b9458> error.
How is it possible to make all the ActionViewer helper functions available?
Newbie.
following suggestion of Tim:
module ContentsHelper
include ActionView::Helpers
def bla
content_tag(:h2, self.title)
end
I can run the bla method as Content.bla in the console. This is perfect!
But when I replacec content_tag with image_tag, then I run into trouble and get this error:
NoMethodError: undefined method `config'
from /Users/sonat/.rvm/gems/ruby-1.8.7-p334/gems/activemodel-3.0.0/lib/active_model/attribute_methods.rb:364:in `method_missing'
from /Users/sonat/.rvm/gems/ruby-1.8.7-p334/gems/activerecord-3.0.0/lib/active_record/attribute_methods.rb:46:in `method_missing'
from /Users/sonat/.rvm/gems/ruby-1.8.7-p334/gems/activerecord-3.0.0/lib/active_record/attribute_methods.rb:44:in `send'
I can see that module that is responsible of the image_tag method is missing "something". I would appreciate if you guys tell me the general approach in finding what is missing and how I could solve the problem.
Looks like you're trying to do something odd like to use the helper method inside your model instead of inside your view. Helper methods are for views, not for models.
Added
Tim asked if I could provide some links to other resources, but really this is such basic stuff that I'm not aware of anything dealing with this. Mostly tutorials deal with unusual things like using helpers outside views.
So instead, here's some code:
app/helpers/contents_helper.rb
module ContentsHelper
def foo
content_tag :p, "Foo"
end
end
app/views/contents/index.html.erb
<h1>Listing Contents</h1>
<%= foo %>
The HTML output when going to /contents URL
<h1>Listing Contents</h1>
<p>Foo</p>
And that's as hard as it is.
content_tag:
Does this work?
module ContentsHelper
include ActionView::Helpers
end
image_tag:
Looks like you'll have to make your models know where the images are located by implementing a #path_to_image(image) method.
I've set up a Gist for us to mock out the features you need here:
https://gist.github.com/1015333
You should be able to download and run forNoNameNo.rb (which should run quietly without errors.)
That file has some examples of what's needed to make image_tag work.
further discussion:
Helpers are probably the weirdest part of Rails. They're declared at the controller level, but are only included at the view level, and rely on weird parts of the controller stack for their info; and yet, the info they are mainly concerned with presenting is the model info. So they're spread across all these weird concerns.
To deal with code-organizations issues arising from all of this, people have tended toward the Presenter pattern. (Also see rbates' version)
That said, if you'd prefer to stray off the beaten path in rails, it's normally really useful to read the source code.
If you're using textmate:
mate `gem which actionpack`../action_view
in Terminal.app should get your there. If you're using another editor/operating system you might have to navigate to whereever gem which actionpack tells you to go.
I use Rails 3.0.4 and RSpec 2.5. In my controllers I use named scopes heavily, for example
#collection = GuestbookEntry.nonreplies.bydate.inclusive.paginate(
:page => params[:page], :conditions => { ... })
In my tests, I want to be able to mock the result of such a query, not the wording. I do not think it makes sense to do something like
GuestbookEntry.stub_chain(:nonreplies, :bydate, ...).and_return(...)
because this test will fail the moment I decide to reorder the named scopes.
With Rails 2.3 and RSpec 1.x, this worked fine: I could write
GuestbookEntry.should_receive(:find).with(:all, :conditions => { ... })
and the above call would be caught and correctly handled. However, with Rails 3, for some reason this does not work any more.
Why? How do I set expectations or stubs on the result of nested scopes? Since everything in Rails 3's ActiveModel is a named scope (thanks to ARel), this must be possible somehow, or tests would indeed be very brittle.
Thanks!
Update: See also issue report on GitHub.
This problem has bugged me for a while too!
I believe the reason the behaviour is different from Rails 2 is because the query is no longer being performed during the variable assignment in the controller. Instead, it's lazy-loaded as required.
I agree with Mark Wilden that it's better to wrap all of these scopes in a larger scope and spec that in your model. This scope clearly has a specific function, so just as one would spec the behaviour of a method which calls several other methods, you would spec the behaviour of a scope that joins several other scopes.
I would wrap such a complicated query in its own scope, and stub that.
UPDATE
I wrongly checked the edgerails guide instead of the currently correct Rails 3 guide (which has no mention of after_initialize). Not sure why the edgerails guide is "incorrect" though - I thought edgerails guide was supposed to be the latest up-to-date guide?
I'm leaving this question as-is just in case someone comes looking for the same "problem".
Macro-style call to after_initialize is the way to go.
Should after_initialize be used as method or macro-style call ?
This works, but gives a deprecation warning:
def after_initialize
logger.info "Called after_initialize"
end
DEPRECATION WARNING: Base#after_initialize has been deprecated,
please use Base.after_initialize :method instead.
This works, and there is no warning:
after_initialize :do_this_after_initialize
def do_this_after_initialize
logger.info "Called after_initialize"
end
But the Active Record Validations and Callbacks Guide in 10.4 after_initialize and after_find says:
...If you try to register
after_initialize or after_find using
macro-style class methods, they will
just be ignored. This behaviour is
due to performance reasons, since
after_initialize and after_find will
both be called for each record found
in the database, significantly slowing
down the queries...
So that means that the macro-style usage is inefficient versus the method-style way?
(I guess the guide is wrong, 'cos code is king :D)
Another Update
A commit here from January 28, 2011, suggests that the correct way is still to use the macro-style call, not a def after_initialize.
The call backs should be used as macro style in your model: http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html