Database Articles

  Home arrow Database Articles arrow Unit Testing a Book Inventory Manageme...

Unit Testing a Book Inventory Management System
By: Apress Publishing
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating:  stars stars stars stars stars / 0

    Table of Contents:
  • Unit Testing a Book Inventory Management System
  • Adding a Fixture for the Many-to-Many Relationship



    Unit Testing a Book Inventory Management System

    (Page 1 of 2 )

    In this seventh part of an article series on the scaffolding feature of Ruby on Rails, we'll continue testing our example book inventory management system. In this part, we'll focus on one-to-many and many-to-many mapping. This article is excerpted from chapter three of the book Practical Rails Projects, written by Eldon Alameda (Apress; ISBN: 1590597818).

    Unit Testing the ActiveRecord Mappings

    You want to be sure that the mapping between authors, books, and publishers works. George won’t be happy at all, if there’s a bug in the code that prevents him from adding the latest best-sellers to the catalog.

    Adding Fixtures for Books and Publishers

    We’ll verify that the mapping works by creating unit tests for the mapping code. But let’s first add some useful data to thebooksandpublishersfixture files, which we’ll use in later tests.

    Opentest/fixtures/books.ymland add the following two books:

    id: 1
    title: Pro Rails E-Commerce
    publisher_id: 1
    isbn: 199-199-199-1
    published_at: <%="%Y-%m-%d") %>
    id: 2
    title: Pro Rails E-Commerce 2nd Edition
    publisher_id: 1
    isbn: 199-199-199-2
    published_at: <%="%Y-%m-%d") %>

    Note that thepublisher_idcolumn has been added to the fixture. This is a reference to a row in the database, which is inserted by thepublishers.ymlfixture file. Currently, no publisher has anidequal to 1, so you’ll need to add the data to thepublishersfixture file to complete the mapping.

    Tip You can write ERB in fixtures in the same way as in views. This allows you to create dynamic fixtures, as demonstrated in thebooks.ymlfixture file, whereTime.nowis used to generate thepublished_atvalue. Although dynamic fixtures are useful in some situations, they should generally be avoided as they make tests more complex and less predictable.

    Next, add a publisher to thetest/fixtures/ publishers.ymlfile:

    id: 1
    name: Apress
    id: 2
    name: Emporium

    Recall that you specify the fixtures that the unit test should load by adding afixturesdeclaration. A couple of tests that we will implement later in this chapter depend on theauthors,publishers, andbooksfixtures. Thebooksfixture has not been added to the test yet, so change thefixturesline in the unit test as follows:

    fixtures :authors, :publishers, :books

    Unit Testing the One-to-Many Mapping

    Now we’ll put the data into use and verify that we can access a collection of books from a publisher. This is done by adding the new test,test_has_many_and_belongs_to_mapping, to thetest/unit/book_test.rbunit test:

    def test_has_many_and_belongs_to_mapping
    apress = Publisher.find_by_name("Apress")
    assert_equal 2, apress.books.size

    book =
    :title => 'Rails E-Commerce 3nd Edition',
    :authors => [Author.find_by_first_name_and_last_name('Christian', 'Hellsten'),
    Author.find_by_first_name_and_last_name('Jarkko', 'Laine')],
    :published_at =>,
    :isbn => '123-123-123-x',
    :blurb => 'E-Commerce on Rails',
    :page_count => 300,
    :price => 30.5

    apress.books << book


    assert_equal 3, apress.books.size
    assert_equal 'Apress',

    Note The unit test doesn’t callbook.saveexplicitly. ActiveRecord is smart enough to know that it must persist the book to the database when the book is added to the author’s collection of books. Also note that you could useassert_difference(introduced in the previous chapter), instead of two calls toassert_equal.

    The unit test performs the following tasks in order:

    1. Look up a publisher and verify that there are two books in the books collection. These two books are inserted by the fixture at the start of the test.
    2. Create a new book and associate two authors with it.
    3. Add the new book to the publisher’s collection of books.
    4. Reload the book and publisher data from the database.
    5. Verify that the publisher has three books, instead of the original count of two.
    6. Verify that the publisher’s name is the one we assigned.

    Note The order the fixtures are listed in is important. The fixture data is inserted in the order it is listed. For example, putting thepublishersfixture after thebooksfixture would result in a foreign key error when the test is run and Rails tries to insert the fixture data:ActiveRecord::StatementInvalid: Mysql::Error: Cannot add or update a child row: a foreign key constraint fails.

    Next, run the unit tests. You should see all tests pass without any errors.

    $ ruby test/unit/book_test.rb

    Loaded suite test/unit/book_test
    Finished in 0.359 seconds.

    3 tests, 13 assertions, 0 failures, 0 errors --------------------------------------------

    To see the SQL that is executed by ActiveRecord behind the scenes, tail thelogs/test.logfile by executing the following command in a separate console window:

    $ tail -f logs/test.log

    This will monitor the log for changes and print them out to the screen.

    Run the unit tests again. You should see the following output from thetest_has_many_ and_belongs_to_mappingtest that you just implemented:

    --------------------------------------------SQL (0.000000) BEGIN
    Publisher Columns (0.000000) SHOW FIELDS FROM publishers
    Publisher Load (0.016000) SELECT * FROM publishers WHERE (publishers.`name` = '
    Book Columns (0.000000) SHOW FIELDS FROM books
    SQL (0.000000) SELECT count(*) AS count_all FROM books WHERE (books.publisher_i
    Author Columns (0.015000) SHOW FIELDS FROM authors
    Author Load (0.000000) SELECT * FROM authors WHERE (authors.`first_name` = 'Joe
    Author Load (0.000000) SELECT * FROM authors WHERE (authors.`first_name` = '
    Book Load (0.000000) SELECT * FROM books WHERE (books.publisher_id = 1)
    SQL (0.000000) INSERT INTO books (`isbn`, `updated_at`, `page_count`, `price
    authors_books Columns (0.016000) SHOW FIELDS FROM authors_books
    SQL (0.000000) INSERT INTO authors_books (`author_id`, `book_id`) VALUES (1, authors_books Columns (0.000000) SHOW FIELDS FROM authors_books
    SQL (0.000000) INSERT INTO authors_books (`author_id`, `book_id`) VALUES (2, Publisher Load (0.000000) SELECT * FROM publishers WHERE ( = 1) LI
    Book Load (0.000000) SELECT * FROM books WHERE ( = 9) LIMIT 1
    SQL (0.000000) SELECT count(*) AS count_all FROM books WHERE (books.publisher_i
    Join Table Columns (0.015000) SHOW FIELDS FROM authors_books
    Author Load (0.000000) SELECT * FROM authors INNER JOIN authors_books ON author
    SQL (0.329000) ROLLBACK

    As you can see from the first and last line in the sample output, each test is wrapped in a transaction, and changes done by the test are rolled back at the end of the test.

    More Database Articles Articles
    More By Apress Publishing

    blog comments powered by Disqus


    - MariaDB, a MySQL Alternative, Opens Foundati...
    - Oracle Supporting HP Itanium Again, Finally
    - Completing a Book Inventory Management System
    - Uploading Images for a Book Inventory Manage...
    - Finishing the Add Book Story for a Book Inve...
    - Integration Testing for a Book Inventory Man...
    - User Stories for a Book Inventory Management...
    - Unit Testing a Book Inventory Management Sys...
    - Testing a Book Inventory Management System
    - Implementing Models for a Book Inventory Man...
    - Book Inventory Application: Publishers and B...
    - Handling Publishers in a Book Inventory Mana...
    - Publisher Administration for Book Inventory ...
    - Book Inventory Management
    - Using the SQL Reference Manual

    Developer Shed Affiliates


    © 2003-2019 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap