From: Greg Willits Date: 2009-07-25T20:27:45+09:00 Subject: Unit Testing and Instance Vars I find myself often wondering about some design choices that result from code which looks similar to the contrived example below. class Places attr_reader :addresses def initialize(some_source) @addresses = [] @raw_addresses = [] load_addresses(some_source) end def load_addresses(some_source) some_source.each do |this_source| @raw_addresses << this_source.address end clean_addresses end private def clean_addresses @raw_addresses.each do |this_address| @addresses << GisTools.normalize_address(this_address) end end end Testing for the final results of @addresses is easy as the instance var is exposed through the attr_reader, but there's two problems: A) Testing clean_addresses is dependent on running load_addresses first in order to acquire data. B) Seeing the intermediate results of @raw_addresses is not possible for testing load_addresses independently because @raw_addresses is not exposed. To fix (A), we could insist on passing parameters. So, we would have: def load_addresses(some_source) some_source.each do |this_source| @raw_addresses << this_source.address end clean_addresses(@raw_addresses) # <----- passed explicitly end private def clean_addresses(raw_addresses) # <----- passed explicitly raw_addresses.each do |this_address| @addresses << GisTools.normalize_address(this_address) end end That would allow clean_addresses to be tested independently and be fed data directly by the test which could be a good thing. Regardless of that advantage, I've often wondered if requiring the passing of instance vars as parameters really is a 'higher standard' or not. I see a lot of code both ways. I tend to believe it's better to be explicit, but admit it feels simpler in many cases to just use the hard-coded instance var. I find myself flip flopping (always a bad thing). Either way, I still can't see the results of @raw_addresses. I find myself having to expose :raw_addresses so that tests can see the results, but there really is no need for :raw_addresses to be exposed, and it shouldn't be a part of the interface. Questions: 1) Any consensus on the parameters issue (*always* pass params, or *usually*)? 2) What's the 'best practice' approach to seeing the results of @raw_addresses? Many thanks for the discussion. -- gw -- Posted via http://www.ruby-forum.com/.