Show Me The Money-7 - At a Canter

Iteration#1 : Day 7/10

Lets start with some ‘functional’ a.ka. controller RETRIEVE tests now. Rails at our service as always, has a test stub awaiting..
Whoa! Whole lot of default tests in there. Let me see if they pass out of the box. No. All 8 fail with exceptions.
Lets comment out all the tests and take them one at a time. Lets take the functionality of listing existing records first to the block..

file:
ShowMeTheMoney\test\functional\inflow_controller_test.rb

class InflowControllerTest < Test::Unit::TestCase
fixtures :credits

def setup
@controller = InflowController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
end
def test_list
get :list

assert_response :success
assert_not_nil assigns(:credits)
assert_equal 2, assigns(:credits).size
assert_template 'list'
end



To run my tests, I’m going to switch to rake. So I type in rake at the project dir and it’ll run all my model and controller tests they say. And it’s true! All Green!
Ok. Next we test if the default index action redirects to list. For that we just uncomment the test_index default test, which checks if the controller “does a list” when the index method is invoked. Green!
Now we move on to ADD.
First we verify the new action by uncommenting default test_new. Green!
Next we verify if we can add a new test by uncommenting test_create. Borriinng! This isn’t fair Rails is taking the fun outta this by doing everything… even writing my tests. I might as well watch some TV if I’m not needed here. Red! We have a red.. seems like it’s time to call in.. ME!
All Green! Spent 5 mins trying to determine the id of the newly created record.. before resorting to SQL to help me get the new record itself.
Let’s take a break!

  def test_create
test_new
numberOfCreditEntries = Credit.count
sDescription = 'my bank'
fAmount = 250000
post :create, :credit => {:description => sDescription, :amount => fAmount}

assert_response :redirect
assert_redirected_to :action => 'list'

assert_equal numberOfCreditEntries + 1, Credit.count
obCreditEntry = Credit.find( :first, :order => 'id DESC')
assert_equal sDescription, obCreditEntry.description
assert_equal fAmount, obCreditEntry.amount
end

VALIDATION
Alright, but what about the devious user’s who shall try to break our sacred system. What if he tries to save with no description or.. no amount?
So we write our concern as a model Test in credit_test.rb
def test_saveWithNoDescriptionFails
obCredit = Credit.find(1)
obCredit.description = " "

assert !obCredit.save, "Record saved without description!"
assert_equal 1, obCredit.errors.count
assert_equal "X", obCredit.errors.on(:description)
end

Red! The “X” is to check what the std error message is for validates_presence_of validator on the console when the test fails.
1) Failure:
test_saveWithNoDescriptionFails (CreditTest) [test/unit/credit_test.rb:37]:
Record saved without description!.
is not true.

3 tests, 12 assertions, 1 failures, 0 errors
So we add our tiny line to the Credit class
class Credit < ActiveRecord::Base
validates_presence_of :description
end


The next run tells us that the correct error message is “can’t be blank”. Obvious.. sheesh! Update our test. Green!

One more to check that amount is numeric, another to test that the amount is always positive. We also extracted a method to fetch the first record.
Adding the Is positive test broke the earlier Is numeric test. But a little tweaking and we’re in the green
file: ShowMeTheMoney\test\unit\credit_test.rb

def test_saveWithNoAmountFails
obCredit = getFirstEntry
obCredit.amount = " "

assert !obCredit.save, "Record saved with non-numeric amount!"
assert_equal 1, obCredit.errors.count
assert_equal "is not a number", obCredit.errors.on(:amount)
end

def test_saveWithZeroAmountFails
obCredit = getFirstEntry
obCredit.amount = 0

assert !obCredit.save, "Credit of amount 0 saved"
assert_equal 1, obCredit.errors.count
assert_equal "should be greater than 0", obCredit.errors.on(:amount)
end

private
def getFirstEntry
Credit.find(1)
end


credit.rb
class Credit < ActiveRecord::Base
validates_presence_of :description
validates_numericality_of :amount

protected
def validate
if (errors.on(:amount).nil?) && (amount <= 0)
errors.add(:amount, "should be greater than 0")
end
end
end


What happens if amount is assigned a nil value? Modified saveWithNoAmountFails and confirmed that it is caught and handled with an error message. Revert.

End of Day7


















No comments:

Post a Comment