- Improved functional tests
- View tests
If you’re developing a rails app and you’re using test/unit then view_test gives you the ability to achieve a clean separation between functional tests and view tests. view_test is a direct influence of rspec and Test::Rails by zenspider.
Improved functional tests
Functional tests are now simpler. You no longer have to set things up so your test can successfully render it’s template. Instead you can make an expectation against an explicit render call or you can render the template that would have been rendered.
Here’s a few examples: (all code examples are written with “behaviors”:http://behaviors.rubyforge.org syntax which is another extension to test/unit to give it nicer syntax):
Expecting an implicit call to the default template
# in the controller you have the action 'show' # Note: there is no call to render def show end # in the test class ProductsControllerTest < Rails::ControllerTest::TestCase should "render the show template on #show" do expect_render :action => "show" get :show end # ....
Expecting an explicit call to another action
# in the controller you have the action 'show' # Note: the explicit call to render def show render :action => "index" end # Note: the explicit call to render def list render :template => "blah" end # in the test class ProductsControllerTest < Rails::ControllerTest::TestCase should "render the show template on #show" do expect_render :action => "index" get :show end should "render the template blah on #list" do expect_render :template => "blah" get :list end # ...
Stubbing the call to render and checking the rendered template
# in the controller you have the action #show # Note: the explicit call to render def show render :action => "index" end # in the test class ProductsTest < Rails::ControllerTest::TestCase should "render the products/index template on #show" do stub_render get :show assert_template "index" end
The benefit of this is that you can successfully use mocks in your functional tests without having to try to compensate for things in your views. Your functional tests now only really test your controllers.
Migrating to Improved Functional Tests
When you use stub_render or expect_render in an individual test only that test will be updated to use the stub or render. This allows you to migrate one test at a time to improved functional tests without having to change everything at one.
View tests are isolated unit tests for your views. One important feature of this is that you can expect or stub “render :partial” calls inside of a view. In fact you have to expect or stub them. There is no way to allow a “render :partial” to pass through to the real view. This is a implementation decision to enforce the convention of keeping a 1:1 test to template ratio.
Here’s an example:
class ScoreboardsPartialViewTest < Rails::ViewTest::TestCase # this is optional if you name your test case well controller_name 'scoreboards' def setup # assign view level instance variables assigns[:scores] = [ stub(:player => "joe", :score => 100), stub(:player => "bob", :score => 200) ] end should "format points with commas" expect_helper(:format_points).with(100).returns("joe's points") expect_helper(:format_points).with(200).returns("bob's points") render :partial => "scoreboard/_scoreboard" assert_select '#scoreboard .points', /joe's points/, "didn't call the helper" assert_select '#scoreboard .points', /bob's points/, "didn't call the helper" end end
Downloading / Installing
You can install view_tests as a rails plugin. It has been tested with Rails Edge REVISIONS 7155 and later.
script/plugin install http://continuous.rubyforge.org/svn/tags/view_test-0.9.0
You can also download the tgz file from “rubyforge”:http://continuous.rubyforge.org .
view_test relies on:
- Mocha 0.5.2 or higher - “rubyforge page”:http://mocha.rubyforge.org”
- Metaid 1.0 or higher - “rubyforge page”:http://rubyforge.org/frs/?groupd_id=1272 and “_why’s metaid page”:http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html
The goal of view_test isn’t to stop people from migrating to rspec or Test::Rails. It exists to allow people who have decided to use test/unit on new code or existing code to achieve a better level of testing in Rails.
blog comments powered by Disqus