So, here's the deal. I'm currently working in a Ruby on Rails environment and have been for ~1 year now. Before that I was in C++/Java land for almost a decade. I'm (still) trying to figure out what the Ruby way is when it comes to asserts.
I'm not worried about the technical detail. I know TestUnit has asserts which can be used in the testing environment and I know I can add my own assert methods to my Ruby project and use them in production Rails to lock down known conditions. The question is: What is the Ruby way for ensuring something in code that I know should/not happen?
For the record, I've been asserting in开发者_高级运维 tests and raising in production. I still can't help but miss my production asserts...
Asserts really shouldn't be used in production code for two reasons.
assert x
is very functional, and as such hard to read. Using a raise/if combo adds readability.assert doesn't make it clear what error will be raised if the condition fails. While,
raise ObscureButInformitiveError if condition
lets the application layers further up do something relveant. Such as emailing an admin, or writing to a perticular log.
Let the error happen, then check the logs for what went wrong, then fix it.
Rails catches all uncaught exceptions automatically, it will only mess up the single request the error happened in.
There's no official non-test assertions in Ruby, but there are gems.
For instance Jim Weirich's Given looks promising. Although its main focus is testing environments (rspec / minitest), but it also:
... provides three assertions meant to be used in non-test/non-spec code. For example, here is a square root function decked out with pre and post-condition assertions.
require 'given/assertions' require 'given/fuzzy_number' include Given::Assertions include Given::Fuzzy def sqrt(n) Precondition { n >= 0 } result = Math.sqrt(n) Postcondition { result ** 2 == about(n) } result end
To use the non-testing assertions, you need to require the
'given/assertions'
file and then include theGiven::Assertions
module into what ever class is using thePrecondition
/Postcondition
/Assert
methods. The code block for these assertions should always be a regular Ruby true/false value (the should and expect methods from RSpec are not available).Note that this example also uses the fuzzy number matching, but that is not required for the assertions themselves.
精彩评论