ProblemIt's important that your test database contains known data that is common to each test case for the model being tested. You don't want your tests to pass or fail depending on what's in the database when they run; that defeats the whole purpose of testing. You have created data to test the boundary conditions of your application, and you want an efficient way to load that data into your database without using SQL. SolutionUse YAML to create a file containing test fixtures to be loaded into your test database. Your database contains a single books table as created by the following migration: db/migrate/001_build_db.rb: class BuildDb < ActiveRecord::Migration def self.up create_table :books do |t| t.column :title, :string t.column :isbn, :string t.column :ean, :string t.column :upc, :string t.column :edition, :string end end def self.down drop_table :books end end Create a Book model using the Rails generate script (notice the test scaffolding that's created by this command): $ ruby script/generate model book exists app/models/ exists test/unit/ exists test/fixtures/ create app/models/book.rb create test/unit/book_test.rb create test/fixtures/books.yml Now, create a fixture containing your test data in the books.yml file under the test/fixtures directory: test/fixtures/books.yml: perl_cookbook: id: 1 title: Perl Cookbook isbn: 957824732X ean: 9789578247321 upc: 636920527114 edition: 1 java_cookbook: id: 2 title: Java Cookbook isbn: 9867794141 ean: 9789867794147 upc: 236920522114 edition: 1 mysql_cookbook: id: 3 title: MySQL Cookbook isbn: 059652708X ean: 9780596527082 upc: 636920527084 edition: 2 Fixtures are loaded by the Test::Unit module by passing the name of the fixture file, without the extension, as a symbol to the fixtures method. The following unit test class shows the books fixtures being loaded with a test confirming success: test/unit/book_test.rb: require File.dirname(__FILE__) + '/../test_helper' class BookTest < Test::Unit::TestCase fixtures :books def test_fixtures_loaded perl_book = books(:perl_cookbook) assert_kind_of Book, perl_book end end DiscussionYAML is a data serialization format designed to be easily readable and writable by humans, as well as by scripting languages such as Python and Ruby. YAML is often used for data serialization and configuration settings, where it serves as a more transparent alternative to XML or a custom configuration language. Before it runs each test case, the Test::Unit module uses the solution's fixture file (books.yml) to initialize the books table of the test database. In other words, each test case starts with a fresh copy of the test data, just as it appears in the YAML fixture. This way, tests can be isolated with no danger of side effects. The test_fixtures_loaded test case of the BookTest class tests that the book fixtures are loaded successfully and that an Active Record Book object is created. Individual records in a YAML fixture are labeled for convenient reference. You can use the books fixture accessor method to return book objects by passing it one of the fixture labels. In the solution, we return an object representing the Perl Cookbook by calling books(:perl_cookbook). The assertion tests that this object is, in fact, an instance of the Book class. The following output shows the successful results of running the test: $ ruby ./test/unit/book_test.rb Loaded suite test/unit/book_test Started . Finished in 0.05485 seconds. 1 tests, 1 assertions, 0 failures, 0 errors See Also
|