7.2 Iteration B2: Unit Testing 6.3 Playtime
Augment the model with a few vailidity checks.
Various validations: required, numeric, positive, and unique
edit app/models/product.rb
class Product < ActiveRecord::Base
validates :title, :description, :image_url, presence: true
validates :price, numericality: {greater_than_or_equal_to: 0.01}
validates :title, uniqueness: true
validates :image_url, allow_blank: true, format: {
with: %r{\.(gif|jpg|png)\Z}i,
message: 'must be a URL for GIF, JPG or PNG image.'
}
end
Demonstrate failures.
get /products/new
post /products
Demonstrate more failures.
get /products/new
post /products
edit app/models/product.rb
class Product < ActiveRecord::Base
validates :title, :description, :image_url, presence: true
validates :price, numericality: {greater_than_or_equal_to: 0.01}
validates :title, uniqueness: true
validates :image_url, allow_blank: true, format: {
with: %r{\.(gif|jpg|png)\Z}i,
message: 'must be a URL for GIF, JPG or PNG image.'
}
end
Now run the tests... and watch them fail :-(
rake test
Run options: --seed 52131
# Running tests:
Finished tests in 0.004569s, 0.0000 tests/s, 0.0000 assertions/s.
0 tests, 0 assertions, 0 failures, 0 errors, 0 skips
Run options: --seed 63536
# Running tests:
F.....F
Finished tests in 0.603442s, 11.6001 tests/s, 16.5716 assertions/s.
1) Failure:
test_should_create_product(ProductsControllerTest) [/home/rubys/git/awdwr/edition4/work-200/depot/test/controllers/products_controller_test.rb:20]:
"Product.count" didn't change by 1.
Expected: 3
Actual: 2
2) Failure:
test_should_update_product(ProductsControllerTest) [/home/rubys/git/awdwr/edition4/work-200/depot/test/controllers/products_controller_test.rb:39]:
Expected response to be a <redirect>, but was <200>
7 tests, 10 assertions, 2 failures, 0 errors, 0 skips
Errors running test:functionals! #<RuntimeError: Command failed with status (1): [ruby -I"lib:test" -I"/home/rubys/.rvm/gems/ruby-2.0.0-p0@global/gems/rake-10.0.3/lib" "/home/rubys/.rvm/gems/ruby-2.0.0-p0@global/gems/rake-10.0.3/lib/rake/rake_test_loader.rb" "test/{controllers,mailers,functional}/**/*_test.rb" ]>
Solution is simple, provide valid data.
edit test/controllers/products_controller_test.rb
require 'test_helper'
class ProductsControllerTest < ActionController::TestCase
setup do
@product = products(:one)
@update = {
title: 'Lorem Ipsum',
description: 'Wibbles are fun!',
image_url: 'lorem.jpg',
price: 19.95
}
end
test "should get index" do
get :index
assert_response :success
assert_not_nil assigns(:products)
end
test "should get new" do
get :new
assert_response :success
end
test "should create product" do
assert_difference('Product.count') do
post :create, product: @update
end
assert_redirected_to product_path(assigns(:product))
end
# ...
test "should update product" do
patch :update, id: @product, product: @update
assert_redirected_to product_path(assigns(:product))
end
# ...
end
Tests now pass again :-)
rake test
Run options: --seed 53509
# Running tests:
Finished tests in 0.004458s, 0.0000 tests/s, 0.0000 assertions/s.
0 tests, 0 assertions, 0 failures, 0 errors, 0 skips
Run options: --seed 34864
# Running tests:
.......
Finished tests in 0.488618s, 14.3261 tests/s, 26.6056 assertions/s.
7 tests, 13 assertions, 0 failures, 0 errors, 0 skips