I'm using rr (the mocking framework) and rspec with ruby-on-rails. Also, I'm using the collection short hand for partial rendering. My question: How do I correctly fill out the the following view spec?
describe 'my_view' do
before(:each) do
assigns[:models] = Array.new(10, stub(Model))
end
it "should render the 'listing' partial for each model" do
# help me write something that actually verifies this
end
end
I've tried a few examples from the rspec book, rspec docs, and rr docs. Everything I try seems to leave me with runtime errors in the test - not failed assertions. Rather than show all the transformations I've tried, I figured all I'd need if someone showed me one that actually worked. I'd be good to go from there.
I would suggest asserting the presence of some HTML that the "listing" partial should generate. Otherwise, it sounds like you're trying to assert that Rails is technically calling render on the partial? That's the job of the Rails core tests to prove such functionality.
Related
I was wondering if there is a script that can take existing codebase and generate unit tests for each method in controllers. By default all would be passing since they would be empty and i can remove tests i for methods i dont feel important.
This would save huge time and increase testing. Since i'd have to define only what each method should output and not boilerplate that needs to be written.
You really shouldn't be doing this. Creating pointless tests is technical debt that you don't want. Take some time, go through each controller and write a test (or preferably a few) for each method. You'll thank yourself in the long run.
You can then also use test coverage tools to see which bits still need testing.
You can use shared tests to avoid repetition. So for example with rspec, you could add the following to your spec_helper/rails_helper
def should_be_ok(action)
it "should respond with ok" do
get action.to_sym
expect(response).to be_success
end
end
Then in your controller_spec
describe UserController do
should_be_ok(:index)
should_be_ok(:new)
end
I've been reading a ton of docs and SO questions/ answers on all the changes as Rspec has evolved, want to be sure of the answer...
My goal is to use native Rspec-rails (I have 3.2.2) to do integrated controller/view tests that look for 1) CSS classes and 2) ID selectors. In other words given this view snippet:
<!-- staticpages/dashboard -->
<div class="hidden">Something</div>
<div id="creation">This</div>
This should pass (however it should be semantically written):
describe StaticpagesController do
render_views
it "should find everything" do
get :dashboard
expect(response.body).to have_selector("div#creation")
expect(response.body).to have_css("hidden")
expect(response.body).to_not have_selector("div#nothinghere")
end
end
I would like to do this without additional gems like Capybara; is that possible?
Here's a high level of what I've learned so far:
in Rspec 1, the have_tag feature allowed you to do this (http://glenngillen.com/thoughts/using-rspec-have-tag)
in Rspec 2, the have_tag was replaced with webrat's have_selector (have_tag vs. have_selector)
in Rspec 3, webrat support has been removed (http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/)
In my own experimentation, the code above generated:
Expect<long response.body here>.to respond to `has_selector?`
So that has indeed been deprecated. Still, I'd love to know if there's some other way to do this that I don't know about.
IF it turns out I need Capybara to do these fancy matchers, is there a way to do this in my integrated controller/view specs? My understanding is that I have to add type: :feature to the describe StaticpagesController line to use Capybara's matchers. However, the minute I do that, render_views is no longer available (since it's limited to type: :controller). Note, render_views also dies if, per this post (https://www.relishapp.com/rspec/rspec-rails/v/2-99/docs/controller-specs/use-of-capybara-in-controller-specs), I manually include Capybara::DSL into my controller spec. Anyway, I would really like to not have to rewrite my current controller specs into a bunch of feature specs...
It would seem that you want feature specs (with Capybara) more than controller specs as you're not testing any of the things controller specs are typically used to test such as:
whether a template is rendered
whether a redirect occurs
what instance variables are assigned in the controller to be shared with the view
the cookies sent back with the response
Also, you probably want to consider writing feature specs for new apps over controller specs since controller tests will probably be dropped in Rails 5 in favor of the writing of integration/feature tests.
For a description of the different kinds of specs that you could write, and what they're typically used for,
see this SO answer.
I know integration tests are preferred but I need this to be ran in a controller test, I'm testing a gem injecting html code in the view, especially with xhr so this can't be run in a feature spec (if it can, please explain me how :) )
So with rspec controller tests you can assert a selector is present (with capybara) :
response.body.should have_selector('#foobar')
has_selector? will call the all method from capybara to find the selector.
What I want to do is get the last child of body and then assert that its id is something in particular.
AFAIK it's not possible to do this with have_selector.
What I would do is :
all('body:first-child').first.id.should == '#foobar'
However, with Capybara DSL, all is defined like this (more or less):
def all(*args)
page.all(*args)
end
And the page will be empty unless I use visit but it's for integrations specs.
How can I use capybara all method inside an rspec controller test ?
I can't test it right now but after some googling it seems like this would do the trick
def page
Capybara::Node::Simple.new(response.body)
end
Source
Wrong use of .t method in Rails template such
<%= (user.score).t(:context => 'foo') %>
Causes an error
undefined method `t' for 46:Fixnum
The method was called on number.
Now the question is how can this situation can be tested? Where the test code should live, so all the templates will be tested before rendering?
It depends on your choice of testing framework. With the Test::Unit stuff that comes with rails your controller and integration tests render views and so should catch this sort of error. Other forms of integration testing, such as cucumber should also pick up such things.
If you use rspec then you can write view specs: specs that test view rendering in isolation.
Lastly if you find yourself with lots of logic in your views that you want to test, you're probably better off extracting that logic into a helper and writing unit tests/specs for that helper.
AFAIK you don't test the templates itself. But you can test e.g. with cucumber if you get the view results you are expecting. This could be some sort of "template testing".
I'm using Test/Unit with a standard rails 2.1 project. I would like to be able to test Partial Views in isolation from any particular controller / action.
It seemed as though ZenTest's Test::Rails::ViewTestCase would help, but I couldn't get it working, similarly with view_test http://www.continuousthinking.com/tags/view_test
Most of the stuff Google turns up seems quite out of date, so I'm guessing doesn't really work with Rails 2.1
Any help with this much appreciated.
Thanks,
Roland
We're using RSpec in our Rails 2.1 project, and we can do this sort of thing:
describe "/posts/_form" do
before do
render :partial => "posts/form"
end
it "says hello" do
response.should match(/hello/i)
end
it "renders a form" do
response.should have_tag("form")
end
end
However I don't know how much of that you can do with the vanilla Rails testing apparatus.
Found this which may be relevant:
http://broadcast.oreilly.com/2008/10/testing-rails-partials.html
Testing a view without the controller code is a dangerous thing. Your tests might pass but your application might throw an error. Always test against real life situations not artificial ones.