让我们来看看怎样写不使用fixtures的测试。
看cart/line_item的例子:
- 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
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方法给字段赋值来测试: - 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
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
但是我们考虑下面的测试 : - 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
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
- sudo gem install mocha
sudo gem install mocha
然后在test_helper.rb里require mocha: - require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
- require 'test_help'
- require 'mocha'
require File.expand_path(File.dirname(__FILE__) + "/../config/environment") require 'test_help' require 'mocha'
我们这样使用mocha来写CartTest: - 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
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方法