I took the ideas presented here and built a gem called Mustard. Check it out!
There are several expectation/assertion interfaces available for writing tests/specs. Here are some issues I have with them.
- The order of
assert_equals
feels backwards - Oh wait, that should be
assert_equal
(that too) - I like to write the subject first
- Adds 30+ methods to Object
- Any matchers you want to add are another method on Object
- Still too few matchers, so it's ugly:
foo.must_be :<, 10
- too.many.method.calls.to.simulate.english
- The space makes for some awkward syntaxes that cause warnings (when used with
==
,>
, etc.) eq()
and such aren't bad, but may need parenthesis- Pollutes the spec context with methods for each matcher
I haven't used the RSpec expect()
interface enough to know cons.
# should returns an object which can have matchers called on it
5.should.eq 5
5.should.equal 5
# should_not can be used to do a reverse match
5.should_not.equal 7
# some comparison matchers
5.should.be_less_than 8
5.should.be_greater_than 3
5.should.be_lt 8
5.should.be_gt 3
5.should.be_gte 5
true.should.be_true
false.should.be_false
# call the method and see if it is true
[].should.be :empty?
5.should.be :between?, 3, 7
# add matchers
Should.matcher :be_empty do # any args will be passed into block
empty? # runs in the context of the object and returns true/false
end
[].should.be_empty
[].should_not.be_empty # message: Expected [] to not be empty
# add matcher through class
Should.matcher :be_empty, BeEmptyMatcher
class BeEmptyMatcher
# methods in here for defining behavior and messages.
end
I like this because it does not pollute the Object space much (just should
and should_not
). Also every method called after it is simply a matcher. No crazy method chains.
What do you think? If there's enough interest I'll write this up as a plugin for both RSpec-Core and MiniTest.
RSpec has always felt a little heavy to me for some reason. I like minitest but I like the spec style and I feel like I spend more time looking up the methods than I do writing tests, something about it doesn't feel natural and I often feel like I'm doing it wrong.
That being said, this looks pretty clean and solves a lot of your issues and looks like it would solve some of mine, but ruby is so bloated with testing frameworks, plugins for those frameworks, runners, etc, and this would just add another dev dependency to your gemspec. For new users coming in, the options are confusing and overwhelming. I'd rather see something like this get merged into minitest proper – but I guess it'd have to be a plugin first.