在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
在前面我们编写并进行了一些单元测试和功能测试,现在,我们的客户突然要求添加一个功能:系统的每个用户都可以对商品进行查询。 现在,我们来考虑一下查询功能的测试,应该由哪个controller来控制查询操作呢?用户和管理员都可以进行查询操作,我们可以在store_controller.rb或者admin_controller.rb中添加一个search()的Action,但是这里我们添加一个SearchController,并且含有一个方法search。在rails命令行执行命令: depot>ruby script/generate controller Search search 我们看到,在app/controllers和test/functional目录下已经生成了对应的文件。但是现在我们并不关心SearchController的search方法的实现,我们关心的是在测试时我们所期望看到的结果。现在添加测试代码,在test/functional/search_controller_test.rb中添加test_search方法: 我们首先想到的是调用search的Action,然后判断是否得到了响应: get :search, :title => "Pragmatic Version Control" assert_response :success 根据之前的草图,我们应该在页面上显示一个flash信息,所以我们要判断flash信息的文本,以及是否显示了正确的页面: assert_equal "Found 1 product(s).", flash[:notice] assert_template "search/results" 然后我们想要判断查询所得到的商品信息: products = assigns(:products) assert_not_nil products assert_equal 1, products.size assert_equal "Pragmatic Version Control", products[0].title 我们还想判断用来显示查询结果的页面的一些内容,我们查询到的商品会作为列表在页面上显示,我们使用catelog视图相同的css样式: assert_tag :tag => "div", :attributes => { :class => "results" }, :children => { :count => 1, :only => { :tag => "div", :attributes => { :class => "catalogentry" }}} 下面是完整的测试方法: def test_search get :search, :title => "Pragmatic Version Control" assert_response :success assert_equal "Found 1 product(s).", flash[:notice] assert_template "search/results" products = assigns(:products) assert_not_nil products assert_equal 1, products.size assert_equal "Pragmatic Version Control", products[0].title assert_tag :tag => "div", :attributes => { :class => "results" }, :children => { :count => 1, :only => { :tag => "div", :attributes => { :class => "catalogentry" }}} end 现在我们来运行测试:ruby test/functional/search_controller_test.rb 不出意外,会得到下面的结果: test_search(SearchControllerTest) [test/functional/search_controller_test.rb:17]: <"Found 1 product(s)."> expected but was <nil>. 1 tests, 2 assertions, 1 failures, 0 errors 因为我们还没有设置flash的内容,进一步说,我们还没有实现search这个Action。怎样实现,书上给留了个作业。OK,那我们就自己来一步步实现search的Action。 1. 给search方法添加内容: @products = Product.find(:all,:conditions=>['title=?',params[:title]]) if not @products.nil? flash[:notice] = sprintf('Found %d product(s).',@products.size) end
render(:action=>'results')现在运行测试,结果如下: ---------------------------------------------------------------------------- 1) Failure: test_search(SearchControllerTest) [Z:/study/ruby/InstantRails/ruby/lib/ruby/gems/1.8/gems/actionpack…… Z:/study/ruby/InstantRails/ruby/lib/ruby/gems/1.8/gems/actionpack…… test/functional/search_controller_test.rb:19:in `test_search']: expecting <"search/results"> but rendering with <"search/search"> 1 tests, 3 assertions, 1 failures, 0 errors ---------------------------------------------------------------------------- 2. 这次轮到assert_template "search/results"断言出错了,是因为我们还没有results这个View,我们在view目录下添加一个results.rhmtl文件,在search_controller.rb文件中添加一个results的空方法: def results end 还要在search方法中添加一句:render("search/results"),然后再运行测试,结果如下: ---------------------------------------------------------------------------- Finished in 0.125 seconds. 1) Failure: test_search(SearchControllerTest) [Z:/study/ruby/InstantRails/ruby/lib/ruby/gems/1.8/gems/…… Z:/study/ruby/InstantRails/ruby/lib/ruby/gems/1.8/gems/…… expected tag, but no tag found matching {:attributes=>{:class=>"results"}, :tag=>"div", "<h1>Search#results</h1>\n<p>Find me in app/views/search/results.rhtml</p>\n". <nil> is not true. ---------------------------------------------------------------------------- 3. 现在可以看到,就只有最后一个断言assert_tag没有通过了,这个断言是对页面上的元素进行判断的,所以我们来实现results页面。仔细看看断言的内容,我们就知道只要在results.rhtml里添加两个div就可以了,下面是results.rhtml的完整内容: <h1>Search#results</h1> <p>Find me in app/views/search/results.rhtml</p> <div class="results"> <div class = "catalogentry"> </div> </div> 保存,然后再运行测试,激动人心的时刻来临了,所有的断言都通过了!测试OK了,下面是结果: ---------------------------------------------------------- DEPRECATION WARNING: You called render('search/result…… t Z:/study/ruby/InstantRails/ruby/lib/ruby/gems/1.8/g…… Finished in 0.094 seconds. 1 tests, 7 assertions, 0 failures, 0 errors ---------------------------------------------------------- 4. 在实现search.rhtml和results.rhtml的时候,我碰到了一些问题,用测试用例都可以选出数据来,但是通过页面就怎么也不行了,把log里的sql贴出来到phpMyAdmin里执行,也能选出数据,真不知道是怎么回事,自己对rails的理解还不深,自己胡乱写了这些代码,先把代码都帖出来,等自己对rails有更深入的理解的时候看能不能找到问题。同时也请高人指点 search_controller_test.rb: require File.dirname(__FILE__) + '/../test_helper' require 'search_controller' # Re-raise errors caught by the controller. class SearchController; def rescue_action(e) raise e end; end class SearchControllerTest < Test::Unit::TestCase fixtures :products def setup @controller = SearchController.new @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new end def test_search get :search, :title => "Pragmatic Version Control" assert_response :success assert_equal "Found 1 product(s).", flash[:notice] assert_template "search/results" products = assigns(:products) assert_not_nil products assert_equal 1, products.size assert_equal "Pragmatic Version Control", products[0].title assert_tag :tag => "div", :attributes => { :class => "results" }, :children => { :count => 1, :only => { :tag => "div", :attributes => { :class => "catalogentry" }}} end end search_controller.rb class SearchController < ApplicationController def search print(params[:title]) @products = Product.find(:all,:conditions=>['title=?',params[:title]])
if not @products.nil? flash[:notice] = sprintf('Found %d product(s).',@products.size) end print(flash[:notice]) #redirect_to(:action=>'results') render(:action=>'results') end def results
end def index
end end Views下有三个文件:index.rhtml,results.rhtml,search.rhtml index.rhtml: <html> <%= form_tag(:action=>'search',:id=>@products) %>
2023-10-27 2022-08-15 2022-08-17 2022-09-23 2022-08-13 |
请发表评论