icon 《基础 Ruby on Rails》的示例程序asagao与Rails2.2相适应

功能测试开头部分的修改等

上一章中,为了让功能测试中 main 控制台的相关测试通过进行了一系列操作。

接下来尝试 members 控制台的测试。

> ruby test/functional/members_controller_test.rb
(省略)
8 tests, 19 assertions, 1 failures, 2 errors

出现一个失败,两个错误。只是这样的话,应该很快能解决。

失败原因和上次一样,和分页有关。

    # 会员一览
    def index
      (省略)
      
      if params[:group_id]
        @group = Group.find(params[:group_id])
        @members = @group.members.find(:all, options)
        @member_pages = ActionController::Pagination::Paginator.new(
          self, @group.members.size, MEMBERS_PER_PAGE, page)
      else
        @members = Member.find(:all, options)
        @member_pages = ActionController::Pagination::Paginator.new(
          self, Member.count, MEMBERS_PER_PAGE, page)
      end
    end

将这个做如下修改。

    # 会员一览
    def index
      (省略)
      
      if params[:group_id]
        @group = Group.find(params[:group_id])
        @members = @group.members.all(options).paginate(
          :page => params[:page], :per_page => MEMBERS_PER_PAGE)
      else
        @members = Member.all(options).paginate(
          :page => params[:page], :per_page => MEMBERS_PER_PAGE)
      end
    end

然后,将 views/members/index.rhtml 的下面部分

  <% if @member_pages.page_count > 1 -%>
    <div class="pagination">
    <%= my_pagination_links @member_pages %>
    </div>
  <% end -%>

做如下修改。

  <%= will_paginate @members, :previous_label => '上一步', :next_label => '下一步', :inner_window => 2 %>

test_routing 里出现失败了。

  3) Failure:
test_routing(MembersControllerTest)
    [test/functional/members_controller_test.rb:26:in `test_routing'
     /usr/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/testing/setup_and_teardown.rb:60:in `__send__'
     /usr/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/testing/setup_and_teardown.rb:60:in `run']:
The generated path <"/members/99/edit"> did not match <"/members/99;edit">

《基础 Ruby on Rails》是以 Rails 1.2.3 为基础的,但是 Rails 1.2.4 中 URL 的形式稍有改变。

设定 members 这个资源,编辑某成员信息的输入表单的 URL 由 /members/99;edit 变成了 /members/99/edit

这说明,应该修正的不是应用程序本身,而是测试的方法。

请将 est/functional/members_controller_test.rb 的第 26-27 行做如下修改。

    assert_generates 'members/99/edit',
      { :controller => 'members', :action => 'edit', :id => 99 }

虽然测试基本上全部通过,但是出现了警告。

> ruby test/functional/members_controller_test.rb
/home/kuroda/hgrepos/books/kiso_rails/cd-rom/chapter9/app/controllers/members_controller.rb:5:
warning: already initialized constant MEMBERS_PER_PAGE
Loaded suite test/functional/members_controller_test
Started
........
Finished in 0.323797 seconds.

8 tests, 37 assertions, 0 failures, 0 errors

这个警告表示 app/controllers/members_controller 被两次 require。

在 Rails1.2 时代,功能测试的开头是下面这样写的。

require File.dirname(__FILE__) + '/../test_helper'
require 'members_controller'

# Re-raise errors caught by the controller.
class MembersController; def rescue_action(e) raise e end; end

到了 rails2.2 就变得像下面那样简单了。

require 'test_helper'

总之,没有了明确 require 控制台的源代码的必要,控制台也没有了 Re-raise 所捕捉错误的必要。

但是,Rails2.2 在方式上还存在些许问题。

执行 test:functionals 任务将所有功能测试一并执行的情况还好,但是如果想执行个别的测试脚本的话

test/functional/members_controller_test.rb:1:in `require': no such file to load -- test_helper (LoadError)
        from test/functional/members_controller_test.rb:1

像这样 test_helper 不能被 require,导致中止。

以前的话可以像下面这样写,

require File.dirname(__FILE__) + '/../test_helper'

但是 Rails 将生成的功能测试一个一个修改的话有点麻烦。

测试脚本执行时,添加 -Itest 选项是正确的方法,('-' 后面的字符是大写字母 i )

> ruby -Itest test/functional/members_controller_test.rb

Ruby 解释器的 -I 选项,是为了指定加载路径( require 是加载文件时的检索目录)。

如果觉得每次添加 -Itest 选项麻烦的话,请在环境变量 RUBYOPT 中设定‘-Itest’。

bash 的话

> export RUBYOPT=-Itest

Windows 的话

> set RUBYOPT=-Itest

Rails2.2 中这样变更的理由请参照http://github.com/rails/rails/commit/e8170805 (英语)。

这样,members 控制台就 OK 了。

如果执行 test:functionals 测试的话……

92 tests, 296 assertions, 3 failures, 6 errors

失败的次数从 4 减到 3,错误的次数从 8 减到 6。

今天,就先讲到这。

(2008/12/01)