Class | Test::Rails::ViewTestCase |
In: |
lib/test/rails/view_test_case.rb
|
Parent: | Test::Rails::FunctionalTestCase |
ViewTestCase allows views to be tested independent of their controllers. Testcase implementors must set up the instance variables the view needs to render itself.
The test class must be named after your controller class name, so if you‘re testing views for the RouteController you would name your test case RouteViewTest. The test case will expect to find your view files in app/views/route.
The test names should be in the form of test_view_edgecase where ‘view’ corresponds to the name of the view file, and ‘edgecase’ describes the scenario you are testing.
If you are testing a view file named ‘show.rhtml’ your test should be named test_show. If your view is behaves differently depending upon its parameters then you can make the test name descriptive like test_show_photos and test_show_no_photos.
class RouteViewTest < Test::Rails::ViewTestCase fixtures :users, :routes, :points, :photos def test_delete # Set up instance variables for template assigns[:loggedin_user] = users(:herbert) assigns[:route] = routes(:work) # render template for the delete action in RouteController render # assert that there's a form with an action of "/route/destroy" assert_form form_url, :post do # with a hidden id field assert_input :hidden, :id # And a submit button that says 'Delete!' assert_submit 'Delete!' end # And a link back to the route so you don't delete it assert_links_to "/route/show/#{routes(:work).id}", 'No, I do not!' end end
require 'test/test_helper' # Create a dummy controller for layout views. This lets the setup use the # right path with minimum fuss. class LayoutsController < ApplicationController; end class LayoutsViewTest < Test::Rails::ViewTestCase fixtures :users, :routes, :points, :photos def test_default # Template set-up @request.request_uri = '/foo' assigns[:action_title] = 'Hello & Goodbye' # Render an empty string with the 'application' layout. render :text => '', :layout => 'application' # Assert content just like a regular view test. assert_links_to '/', 'Home' assert_links_to '/user', 'Login' deny_links_to '/user/logout', 'Logout' assert_title 'Hello & Goodbye' assert_h 1, 'Hello & Goodbye' end end
Form assertions are now using assert_select, so you don‘t need to pass URLs around everywhere and can instead use a block. (See above example).
The form assertions will still work using the old syntax, but in a future release they will give warnings, then will be removed.
A wrapper assert that calls both assert_input and assert_label.
view:
<%= start_form_tag :controller => 'game', :action => 'save' %> <label for="game_amount">Amount:</label> <% text_field 'game', 'amount' %>
test:
assert_field '/game/save', :text, :game, :amount
Asserts that there is a form whose action is form_action. Optionally, method and enctype may be specified. If a block is given, assert_form behaves like assert_select, so assert_input and friends may be scoped to the selected form.
view:
<%= start_form_tag :action => 'create_file' %> # ...
test:
assert_form '/game/save'
or:
assert_form '/game/save' do # ... end
Asserts a hN tag of level level exists and contains content.
view:
<h3>Recent Builds</h3>
test:
assert_h 3, 'Recent Builds'
Asserts that an image exists with a src of src.
view:
<img src="/images/bucket.jpg" alt="Bucket">
test:
assert_image '/images/bucket.jpg'
Asserts that an input element of type with a name of name, and optionally a value of value exists.
view:
<%= text_field 'game', 'amount' %>
test:
assert_input :text, "game[amount]"
Asserts that a label with a for attribute of for_attribute exists.
view:
<%= start_form_tag :controller => 'game', :action => 'save' %> <label for="game_amount">Amount:</label>
test:
assert_label 'game_amount'
Asserts that there is an anchor tag with an href of href that optionally has content.
view:
<%= link_to 'drbrain', :model => user %>
test:
assert_links_to '/players/show/1', 'drbrain'
Asserts that there is a form using the ‘POST’ method whose action is form_action and uses the multipart content type. If passed a block, works like assert_form.
view:
<%= start_form_tag({ :action => 'create_file' }, :multipart => true) %>
test:
assert_multipart_form '/game/save'
Asserts that there is a form using the ‘POST’ method whose action is form_action. If passed a block, works like assert_form.
view:
<%= start_form_tag :action => 'create_file' %>
test:
assert_post_form '/game/save'
Asserts that a select element with a name of "model[column]" and options with specified names and values exists.
view:
<%= collection_select :game, :location_id, @locations, :id, :name %>
test:
assert_select_tag :game, :location_id, 'Ballet' => 1, 'Guaymas' => 2
Asserts that a submit element with a value of value exists.
view:
<input type="submit" value="Create!" %>
test:
assert_submit 'Create!'
Asserts that a form with form_action has a descendent that matches options exists.
Typically this is not used directly in tests. Instead use it to build expressive tests that assert which fields are in what form.
view:
<%= start_form_tag :action => 'save' %> [...]
test:
assert_tag_in_form '/route/save', :tag => 'table'
Asserts that a textarea with name name and optionally value exists.
view:
<%= text_area 'post', 'body' %>
test:
assert_text_area 'post[body]'
view:
<textarea id="post_body" name="post[body]"> <%= @post.body %> </textarea>
test:
assert_text_area 'post[body]', posts(:post).body
Asserts that a title with title exists.
view:
<title>some content</title>
test:
assert_title 'some content'
Allows the view instance variables to be set like flash:
test:
def test_show assigns[:route] = routes(:work)
Denies the existence of an anchor tag with an href of href and optionally content.
view (for /players/show/1):
<%= link_to_unless_current 'drbrain', :model => user %>
test:
deny_links_to '/players/show/1'
Renders the template. The template is determined from the test name. If you have multiple tests for the same view render will try to Do The Right Thing and remove parts of the name looking for the template file.
By default, render has the added option :layout => false, so if want to test behavior in your layout add :layout => true.
The action can be forced by using the options:
render :action => 'new' render :template => 'profile/index'
A test‘s path parameters may be overridden, allowing routes with additional parameters to work.
By default, a view tests sets the controller and action of a test to the controller name and action name for the test. This may be overriden.
A test involving routes like:
map.workspace '/users/:owner/workspace/:action', :controller => 'workspace', :action => 'workspace'
Can be invoked by setting @path_parameters like this:
def test__app_entry @path_parameters[:owner] = 'bob' @path_parameters[:action] = 'apps' render :partial => 'apps/app_entry' # ... end
render strips off words trailing an _ in the test name one at a time until it finds a matching action. It tries the extensions ‘rhtml’, ‘rxml’, ‘rjs’, and ‘mab’ in order for each action until a view is found.
With this test case:
class RouteViewTest < Test::Rails::ViewTestCase def test_show_photos render end def test_show_no_photos render end end
In test_show_photos, render will look for:
And in test_show_no_photos, render will look for:
If a view cannot be found the test will flunk.