诗歌rails 之 不用fixtures的测试

本文介绍了一种不依赖fixtures的Rails测试方法,通过使用Mocha进行mock测试,简化了测试过程并提高了测试的稳定性。
关键字: Rails test mocha 严重依赖fixtures的测试会变得十分脆弱,并且很难维护。
让我们来看看怎样写不使用fixtures的测试。
看cart/line_item的例子:
ruby代码
  1. class Cart < ActiveRecord::Base  
  2.   has_many :line_items  
  3.   
  4.   def total_weight  
  5.     line_items.to_s.sum(&:weight)  
  6.   end  
  7. end  
  8.   
  9. class LineItem < ActiveRecord::Base  
  10.   belongs_to :cart  
  11.   belongs_to :product  
  12.   belongs_to :delivery_method  
  13.   
  14.   def weight  
  15.     if delivery_method.shipping?  
  16.       product.weight*quantity  
  17.     else  
  18.       0  
  19.     end  
  20.   end  
  21. end  
class Cart < ActiveRecord::Base   has_many :line_items    def total_weight     line_items.to_s.sum(&:weight)   end end  class LineItem < ActiveRecord::Base   belongs_to :cart   belongs_to :product   belongs_to :delivery_method    def weight     if delivery_method.shipping?       product.weight*quantity     else       0     end   end end 
对简单的字段数据我们可以通过使用ActiveRecord生成的build_xxx方法给字段赋值来测试:
ruby代码
  1. class LineItemTest < Test::Unit::TestCase  
  2.   def test_should_have_zero_for_weight_when_not_shipping  
  3.     line_item = LineItem.new  
  4.     line_item.build_delivery_method(:shipping => false)  
  5.     assert_equal 0, line_item.weight  
  6.   end  
  7.   
  8.   def test_should_have_weight_of_product_times_quantity_when_shipping  
  9.     line_item = LineItem.new(:quantity => 3)  
  10.     line_item.build_delivery_method(:shipping => true)  
  11.     line_item.build_product(:weight => 5)  
  12.     assert equal 15, line_item.weight  
  13.   end  
  14. end  
class LineItemTest < Test::Unit::TestCase   def test_should_have_zero_for_weight_when_not_shipping     line_item = LineItem.new     line_item.build_delivery_method(:shipping => false)     assert_equal 0, line_item.weight   end    def test_should_have_weight_of_product_times_quantity_when_shipping     line_item = LineItem.new(:quantity => 3)     line_item.build_delivery_method(:shipping => true)     line_item.build_product(:weight => 5)     assert equal 15, line_item.weight   end end 
但是我们考虑下面的测试 :
ruby代码
  1. class CartTest < Test::Unit::TestCase  
  2.   fixtures :carts, :line_items, :delivery_methods, :products  
  3.   
  4.   def test_total_weight  
  5.     assert_equal 10, carts(:primary).total_weight  
  6.   end  
  7. end  
class CartTest < Test::Unit::TestCase   fixtures :carts, :line_items, :delivery_methods, :products    def test_total_weight     assert_equal 10, carts(:primary).total_weight   end end 
这里我们手动准备cart/line_item数据会非常麻烦,而且total_weight依赖于line_item.weight方法,而weight方法已经测试过了
为了减少麻烦,我们可以使用mock方式来简化测试而不需要fixtures
我们需要先安装mocha
ruby代码
  1. sudo gem install mocha  
sudo gem install mocha 
然后在test_helper.rb里require mocha:
ruby代码
  1. require File.expand_path(File.dirname(__FILE__) + "/../config/environment")  
  2. require 'test_help'  
  3. require 'mocha'  
require File.expand_path(File.dirname(__FILE__) + "/../config/environment") require 'test_help' require 'mocha' 
我们这样使用mocha来写CartTest:
ruby代码
  1. require File.dirname(__FILE__) + '/../test_helper'  
  2.   
  3. class CartTest < Test::Unit::TestCase  
  4.   def test_total_weight_should_be_sum_of_line_item_weights  
  5.     cart = Cart.new  
  6.     cart.line_items.build.stubs(:weight).returns(7)  
  7.     cart.line_items.build.stubs(:weight).returns(3)  
  8.     assert_equal 10, cart.total_weight  
  9.   end  
  10. end  
require File.dirname(__FILE__) + '/../test_helper'  class CartTest < Test::Unit::TestCase   def test_total_weight_should_be_sum_of_line_item_weights     cart = Cart.new     cart.line_items.build.stubs(:weight).returns(7)     cart.line_items.build.stubs(:weight).returns(3)     assert_equal 10, cart.total_weight   end end 
由于前面已经测过了weight方法,这里使用stubs模拟weight方法的返回值,将测试逻辑专注于total_weight方法

转载于:https://www.cnblogs.com/orez88/articles/1520377.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值