From: David Masover Date: 2010-04-08T09:31:09+09:00 Subject: Re: Visibility in tests I'm going to guess that I'm the odd one out here, but... On Tuesday 06 April 2010 07:26:20 pm Bernhard Brodowsky wrote: > I don't know how to apply unit tests to private methods. Usually, I only > use very few private methods and for my small private purposes, it was > okay to just set those few to public, too, but how do you do that in a > good way, if you really do have good reasons for making the methods > private? Don't test them directly. Well, alright, let me take a step back: I agree with Ryan here that they shouldn't be private at all. In a language like Java, I can understand, but in Ruby, your users will have the source code, and even if they don't, they'll have Object#send and instance_variable_get/set. Your best bet is to explicitly document your public API. If people use methods that aren't documented, they get to keep both pieces. However, there are exceptions -- if I recall, Rails will automatically make certain methods inaccessible to mass assignment if they're private or protected. Anyway... Presuming you really do have a good reason for making them private, you probably have an even better reason to not unit test them directly, and certainly not to rely on the state of instance variables in your unit tests. Your tests should verify _behavior_, not the minute details of _state_. As an example: I realize this is about the worst way to do things, but let's pretend you have the following methods on Integers: public def is_prime? factors.empty? end private def factors # ... end Now, your tests should be testing _what_ you actually care about, not _how_ it's implemented. So, instead of testing factors directly, you would test is_prime. Your tests would look something like this: it 'should believe 4 is prime' 5.should be_prime 4.should_not be_prime ... end I realize this makes them more integration tests than unit tests, and maybe I'm missing the point, but I just don't see the use of such fine-grained tests. You want them fine-grained enough to actually catch bugs, but coarse enough that they're actually worth writing.