Tre*_*ean 24 ruby-on-rails ruby-on-rails-3
在Rails 3中测试作用域的最佳方法是什么.在rails 2中,我会做类似的事情:
Rspec的:
it 'should have a top_level scope' do
Category.top_level.proxy_options.should == {:conditions => {:parent_id => nil}}
end
Run Code Online (Sandbox Code Playgroud)
这在rails 3中失败,并为[]:ActiveRecord :: Relation"错误提供了"未定义的方法`proxy_options'.
人们如何测试使用正确的选项指定范围?我看到你可以检查一下arel对象,也许可以对此做出一些期望,但我不确定最好的方法是什么.
adz*_*ies 37
抛开"如何测试"的问题...这里是如何在Rails3中实现类似的东西......
在Rails3中,命名范围的不同之处在于它们只生成Arel关系运算符.但是,调查!
如果你去你的控制台并输入:
# All the guts of arel!
Category.top_level.arel.inspect
Run Code Online (Sandbox Code Playgroud)
你会看到Arel的内部部分.它用于建立关系,但也可以对当前状态进行反省.您会注意到#where_clauses等公共方法.
但是,范围本身有很多有用的内省公共方法,比直接访问@arel更容易:
# Basic stuff:
=> [:table, :primary_key, :to_sql]
# and these to check-out all parts of your relation:
=> [:includes_values, :eager_load_values, :preload_values,
:select_values, :group_values, :order_values, :reorder_flag,
:joins_values, :where_values, :having_values, :limit_value,
:offset_value, :readonly_value, :create_with_value, :from_value]
# With 'where_values' you can see the whole tree of conditions:
Category.top_level.where_values.first.methods - Object.new.methods
=> [:operator, :operand1, :operand2, :left, :left=,
:right, :right=, :not, :or, :and, :to_sql, :each]
# You can see each condition to_sql
Category.top_level.where_values.map(&:to_sql)
=> ["`categories`.`parent_id` IS NULL"]
# More to the point, use #where_values_hash to see rails2-like :conditions hash:
Category.top_level.where_values_hash
=> {"parent_id"=>nil}
Run Code Online (Sandbox Code Playgroud)
使用最后一个:#where_values_hash以与Rails2中的#proxy_options类似的方式测试范围....
Ian*_*nce 27
理想情况下,您的单元测试应将模型(类)及其实例视为黑盒子.毕竟,它不是你关心的实现,而是界面的行为.
因此,不是测试范围是以特定方式实现的(即使用一组特定条件),而是尝试测试它的行为是否正确 - 它返回应该应用的实例,而不返回它不应该返回的实例.
describe Category do
describe ".top_level" do
it "should return root categories" do
frameworks = Category.create(:name => "Frameworks")
Category.top_level.should include(frameworks)
end
it "should not return child categories" do
frameworks = Category.create(:name => "Frameworks")
rails = Category.create(:name => "Ruby on Rails", :parent => frameworks)
Category.top_level.should_not include(rails)
end
end
end
Run Code Online (Sandbox Code Playgroud)
如果您以这种方式编写测试,您可以随意重新考虑实现,而无需修改测试,更重要的是,无需担心在不知不觉中破坏您的应用程序.
这就是我检查它们的方式.想想这个范围:
scope :item_type, lambda { |item_type|
where("game_items.item_type = ?", item_type )
}
Run Code Online (Sandbox Code Playgroud)
获得所有game_items,其中item_type等于一个值(如'Weapon'):
it "should get a list of all possible game weapons if called like GameItem.item_type('Weapon'), with no arguments" do
Factory(:game_item, :item_type => 'Weapon')
Factory(:game_item, :item_type => 'Gloves')
weapons = GameItem.item_type('Weapon')
weapons.each { |weapon| weapon.item_type.should == 'Weapon' }
end
Run Code Online (Sandbox Code Playgroud)
我测试武器阵列只包含武器item_types而不是规格中指定的其他类似手套的东西.
| 归档时间: |
|
| 查看次数: |
10958 次 |
| 最近记录: |