ProblemCreating test fixtures for simple tables that don't have any relations to other tables is easy. But you have some Active Record objects with many-to-many associations. How do you populate your test database with data to test these more complex relationships? SolutionYour database contains assets and tags tables as well as a join table named assets_tags. The following migration sets up these tables: db/migrate/001_build_db.rb: class BuildDb < ActiveRecord::Migration def self.up create_table :assets do |t| t.column :name, :string t.column :description, :text end create_table :tags do |t| t.column :name, :string end create_table :assets_tags do |t| t.column :asset_id, :integer t.column :tag_id, :integer end end def self.down drop_table :assets_tags drop_table :assets drop_table :tags end end The Asset and Tag classes have Active Record many-to-many associations with each other: app/models/asset.rb: class Asset < ActiveRecord::Base has_and_belongs_to_many :tags end app/models/tag.rb: class Tag < ActiveRecord::Base has_and_belongs_to_many :assets end To create YAML test fixtures to populate these tables, start by adding two fixtures to tags.yml: test/fixtures/tags.yml: travel_tag: id: 1 name: Travel office_tag: id: 2 name: Office Likewise, create three asset fixtures: test/fixtures/assets.yml: laptop_asset: id: 1 name: Laptop Computer desktop_asset: id: 2 name: Desktop Computer projector_asset: id: 3 name: Projector Finally, to associate the tags and assets fixtures, we need to populate the join table. Create fixtures for each asset in assets_tags.yml with the id from each table: test/fixtures/assets_tags.yml: laptop_for_travel: asset_id: 1 tag_id: 1 desktop_for_office: asset_id: 2 tag_id: 2 projector_for_office: asset_id: 3 tag_id: 2 DiscussionYou include one or more fixtures by passing them as a comma-separated list to the fixtures method. By including all three fixture files in your test case class, you'll have access to assets and can access their tags: test/unit/asset_test.rb: require File.dirname(__FILE__) + '/../test_helper' class AssetTest < Test::Unit::TestCase fixtures :assets, :tags, :assets_tags def test_assets laptop_tag = assets('laptop_asset').tags[0] assert_kind_of Tag, laptop_tag assert_equal tags('travel_tag'), laptop_tag end end See Also
|