Wednesday, September 13, 2006

Ruby Stub Variations: TestStub

Ruby Stub Variations: Introduction
Ruby Stub Variations: OpenStruct
Ruby Stub Variations: TestStub
Ruby Stub Variations: Struct
Ruby Stub Variations: Stubba

As I mentioned in my last entry, OpenStruct provides the desired simplicity when creating a stub. However, OpenStruct's inability to stub previously defined methods made it painful to work with when stubbing ActiveRecord::Base subclass instances. To resolve this issue my team borrowed some of the code from OpenStruct and wrote their own TestStub class. I previously wrote about this decision so I wont go too deep into detail; however, the general idea is that defining methods, instead of depending on a hash, resolved this issue. The implementation we ended up using was a bit simpler than the previous example though.
class TestStub
def initialize(*should_respond_to)
@table = {}
should_respond_to.each do |item|
create_readers(item) and next if item.kind_of? Hash
create_writer(item) and next if item.kind_of? Symbol
end
end

def create_readers(item)
item.each_pair do |key, val|
self.class.send(:define_method, key.to_sym) { val }
end
end

def create_writer(item)
self.class.send(:define_method, :"#{item}=") { }
end
end
TestStub provided us with the same ease of use that OpenStruct provided, thus the solution to example test is basically the same.
def test_values_are_appened_to_insert_statement
statement = Insert.into[:table_name].values do
TestStub.new(:to_sql=>'select column1, column2 from table2')
end
assert_equal "insert into table_name select column1, column2 from table2", statement.to_sql
end
TestStub never gave us any trouble; however, it was one more piece of code (and tests) to maintain.

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.