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
[deprecated] I18n.enforce_available_locales will default to true in the future. If you really want to skip validation of your locale you can set I18n.enforce_available_locales = false to avoid this message.
[deprecated] I18n.enforce_available_locales will default to true in the future. If you really want to skip validation of your locale you can set I18n.enforce_available_locales = false to avoid this message.
Loaded suite /home/rubys/.rvm/gems/ruby-1.9.2-p320/gems/rake-10.1.1/lib/rake/rake_test_loader
Started
Finished in 0.002210 seconds.
0 tests, 0 assertions, 0 failures, 0 errors, 0 skips
[deprecated] I18n.enforce_available_locales will default to true in the future. If you really want to skip validation of your locale you can set I18n.enforce_available_locales = false to avoid this message.
Loaded suite /home/rubys/.rvm/gems/ruby-1.9.2-p320/gems/rake-10.1.1/lib/rake/rake_test_loader
Started
ProductsControllerTest:
FAIL should create product (0.28s)
"Product.count" didn't change by 1.
<3> expected but was
<2>.
/home/rubys/git/rails/activesupport/lib/active_support/testing/assertions.rb:60:in `block in assert_difference'
PASS should destroy product (0.00s)
PASS should get edit (0.01s)
PASS should get index (0.03s)
PASS should get new (0.01s)
PASS should show product (0.01s)
FAIL should update product (0.01s)
Expected response to be a <:redirect>, but was <200>
/home/rubys/git/rails/actionpack/lib/action_dispatch/testing/assertions/response.rb:38:in `assert_response'
Finished in 0.354985 seconds.
7 tests, 9 assertions, 2 failures, 0 errors, 0 skips
Errors running test:functionals!
Solution is simple, provide valid data.
edit test/functional/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
put :update, id: @product.to_param, product: @update
assert_redirected_to product_path(assigns(:product))
end
# ...
end
Tests now pass again :-)
rake test
[deprecated] I18n.enforce_available_locales will default to true in the future. If you really want to skip validation of your locale you can set I18n.enforce_available_locales = false to avoid this message.
[deprecated] I18n.enforce_available_locales will default to true in the future. If you really want to skip validation of your locale you can set I18n.enforce_available_locales = false to avoid this message.
Loaded suite /home/rubys/.rvm/gems/ruby-1.9.2-p320/gems/rake-10.1.1/lib/rake/rake_test_loader
Started
Finished in 0.002386 seconds.
0 tests, 0 assertions, 0 failures, 0 errors, 0 skips
[deprecated] I18n.enforce_available_locales will default to true in the future. If you really want to skip validation of your locale you can set I18n.enforce_available_locales = false to avoid this message.
Loaded suite /home/rubys/.rvm/gems/ruby-1.9.2-p320/gems/rake-10.1.1/lib/rake/rake_test_loader
Started
ProductsControllerTest:
PASS should create product (0.23s)
PASS should destroy product (0.01s)
PASS should get edit (0.04s)
PASS should get index (0.03s)
PASS should get new (0.01s)
PASS should show product (0.01s)
PASS should update product (0.01s)
Finished in 0.334972 seconds.
7 tests, 10 assertions, 0 failures, 0 errors, 0 skips