So, yesterday I was discussing with my team if it is a waste of time to test initialize method in ruby using rspec.
Usually, when we test a method which needs to instantiate a class (.new), initialize method is implicitly tested. But we only "implicit test" private methods and initialize is a public method.
Another point is that initialize should only create attributes without complex logic.
What do you think about that?
Top comments (4)
Yes, all Ruby code should be tested.
Ruby is a non-compiled language and the only way to know if the code is even remotely correct is to run it. That could be said for all languages, but in compiled languages you get at least some level of analysis done by the compiler. In Ruby you are on your own. Even the most obvious issue might surface only at runtime.
Now, I am not suggesting that you should go crazy trying to get to 100% code coverage. In theory it would be a fine goal to have, but it in practice is simply too expensive.
When it comes to initializers that have a complex logic with many corner cases, it is particularly important to have tests and strive for a decent code coverage. The reason is that initializers are the entry point for the operations of a class instance, and defects in an initializer are particularly problematic. They have a high probability of creating issues in the future as you use the class in different ways.
Now... if an initializer is particularly complex, I'd question the design. A class with complex initializers can probably be refactored and its functionality distributed to simpler objects or refactored to be contained to more generic methods that can be tested separately.
I would definitely highlight the issue of complex initialisers being questionable. The purpose of the initialiser is surely to set instance variables, and I would see anything else that it does as a code smell.
That reduces the initialiser to setting instance variables, and the values of those instance variables may not by themselves be publicly available.
Furthermore, if you test an initialiser it seems to me that you should be testing an interface between your class and the rest of the code base, and it is generally that interfacing action that should be the subject of the test.
This is probably not a good enough point to avoid testing it. The method is still part of something complex and the tests help ensure the acceptability of the code as a whole.
However, yes it is implicitly tested most of the time. If you hold that pattern to be true throughout the app, than you probably don't need to test it. But that hardly seems like a universal truth. I could think of times you'd just call
Object.new
, perhaps to pass into aform_for
.It seems like part of the reason we typically don't test private methods is that it's sort of inconvenient and perhaps messy to do so. And for that reason, we can settle on testing them implicitly. Testing
Object.new
seems a lot more straightforward.We do not test
Object.new
but in writing this, I feel like we should. But I'd love to hear my points debated or anyone else's thoughts on the issue.Those are the points I trust in. Even if it is implicitly tested, it still is a public method.