The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
Testing: Replace Collaborator with Stub

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Jay Fields

Posts: 765
Nickname: jayfields
Registered: Sep, 2006

Jay Fields is a software developer for ThoughtWorks
Testing: Replace Collaborator with Stub Posted: May 27, 2007 11:51 AM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Jay Fields.
Original Post: Testing: Replace Collaborator with Stub
Feed Title: Jay Fields Thoughts
Feed URL: http://feeds.feedburner.com/jayfields/mjKQ
Feed Description: Blog about Ruby, Agile, Testing and other topics related to software development.
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Jay Fields
Latest Posts From Jay Fields Thoughts

Advertisement
If you've done much testing I'm sure you've been annoyed by cascading failures. Cascading failures are most often a symptom of tests that rely on concrete classes instead of isolating the class under test. A solution for creating more robust tests is to replace the collaborators with stubs.

Example: Testing the AccountInformationPresenter independent of the Account class.

The prefactored test involves testing the presenter by creating the Account ActiveRecord instance and testing that the presenter correctly formats the phone number of the instance.
class AccountInformationPresenterTest < Test::Unit::TestCase
def test_phone_number_is_formatted_correctly
Account.delete_all
Account.create(:phone_number => '1112223333')
account = Account.find :first
presenter = AccountInformationPresenter.new(account.id)
assert_equal "(111) 222-3333", presenter.phone_number
end
end
The potential issue with the above test is that if the Account class changes this test could fail. For example, if a validation is added to Account that verifies that the area code of the phone number is valid the above test will fail despite the fact that nothing about the presenter changed.

The same behavior of the presenter can be tested without relying on an actual instance of the Account class. The following test takes advantage of the Mocha mocking and stubbing framework. The new version of the test mocks the interaction with the Account class and returns a stub instead of an actual account instance.
class AccountInformationPresenterTest < Test::Unit::TestCase
def test_phone_number_is_formatted_correctly
Account.expects(:find).returns(stub(:phone_number => '1112223333'))
presenter = AccountInformationPresenter.new(:any_number)
assert_equal "(111) 222-3333", presenter.phone_number
end
end
The new test will not fail regardless of any changes to the Account class.

Where the refactoring applies
This refactoring is most often applicable to unit tests. The unit test suite is often a good place to test edge cases and various logic paths. However, there is much value in testing collaboration among the various classes of your codebase. For these reasons you wouldn't want to apply this refactoring to your functional tests. If you do apply this refactoring, you should ensure you have proper coverage in the functional suite.

The code for the AccountInformationPresenter remains the same regardless of test implementation and is only shown for completeness.
class AccountInformationPresenter
def initialize(account_id)
@account = Account.find(account_id)
end

def phone_number
@account.phone_number.gsub(/(\d\d\d)(\d\d\d)(\d\d\d\d)/, '(\1) \2-\3')
end
end

Read: Testing: Replace Collaborator with Stub

Topic: ZenTest version 3.6.0 has been released! Previous Topic   Next Topic Topic: Ostrava on Rails, part 2

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use