Monday, August 15, 2011

Should You Unit Test Interaction with Static Methods?

No. You should not. Here's an example:

def a_good_method
Logger.log(self, "This is a call to a static log method")
# do some other thing here
end

If you are somehow mocking this static method, you are potentially making it dangerous for other places where this static method is used. Eventually, this will create red test results that are hard to find and make your tests dependent on each other.

Friday, August 12, 2011

How to list all classes that include a module?

Here's the code:
module MyModule
def self.included base
included_classes << base unless included_classes.include?(base)
end
def self.included_classes
@@included ||= []
end
end
class ClassA
include MyModule
end
class ClassB
include MyModule
end
puts MyModule.included_classes

Tuesday, August 09, 2011

Should you unit test methods with a lot of mocking?

Well, anytime you have a lot of mocking, it is probably a smell. Particularly, a first smell is violation of the law of demeter. However, we were having discussion about whether or not we should write unit test for something like the following example:

#example_code
def search(query, page_number)
third_party_search_library.search("*{query}*").from(page_number * page_size).size(page_size).matched_results
end
#example_unit_test
it "should search for partial match and return paged result" do
third_party_search_library.should_receive(:search).with('*new york*').and_return(cities)
cities.should_receive(:from).with(40).and_return(cities)
cities.should_receive(:size).with(20).and_return(cities)
City.search('new york', 2).should == cities
end


As you can see, this method actually does a quite important task. It invokes the search method with specific parameters that will determine your search results. Now, we were debating whether or not the example unit test actually brings any value.

Here's what we have discussed:
Pros:
It confirms that you are actually calling the third party method with the right parameter.
Cons:
The test is too tightly coupled with the implementation, so it will break if something changes inside the method irrespective of its actual output.

But we failed to come to an unanimous decision on its usefulness. We all agreed on the point that it definitely needed some integration tests to make sure the search had actually worked.

Here are two questions for you:

  1. Would you skip the unit test altogether for this method and rely completely on an integration test? Why/Why not?
  2. If you are to rewrite this code, how would you write this using TDD?

Looking forward to see your input on this!

Friday, August 05, 2011

Ruby present? Method

Ruby has a nice little keyword called unless, that checks the opposite of if. So, you are probably used to a code like this:

return customer.first_name unless customer.nil?

If you haven't used present? before, you can in fact turn the above unless into a more familiar and easy to understand if statement:

return customer.first_name if customer.present?

So, in most cases when you are using unless with a negative condition, you can use present? and if instead. I find it way easier to read.

present? does the opposite of blank?. So, you will get the following:

nil.present? #=> false
[].present? #=> false
"hello".present? => true
["a"].present? #=> true
Hope it helps!