Ramcrest: a Ruby port of Hamcrest Hamcrest is a powerful set of classes and functions that allow buildingup complicated matching expressions. The matchers provide useful descriptionsof what they are trying to match, as well as a description of why a particularobject is not matched (a mismatch description). The tests for the various matchers should provide great examples of usage becauseeach matcher is actually tested using the Ramcrest framework. There are integrations into MiniTest via assert_that(actual, matcher) andinto RSpec 2.11 via expect(actual).that matcher . How do I use this?In your tests you need to which will bring in all of the base Ramcrest matchers and give you a newassert_that(subject, matcher) assertion for your MiniTest tests. Once youhave loaded the matchers you can now include them in your tests and startmatching away! describe My::Funky::Class do include Ramcrest::HasAttribute include Ramcrest::IncludesExactly it "only knows the funky chicken by default" do assert_that My::Funky::Class.new, has_attribute(:dances, includes_exactly(:funky_chicken)) endend This matches an object that has an attribute (actually just a no arg method)called dances where the result of calling that method is an Enumerable thatincludes only the symbol :funky_chicken . What matchers are included?This is the list of current matchers. This list will grow over time and somenames might change in order to allow for integration into various testingframeworks. Ramcrest::Aint - Logical negation.
assert_that 1, aint(2)assert_that [2], aint(includes_exactly(1)) Ramcrest::Anything - Everything's OK!
assert_that "a value", anything Ramcrest::Comparable - Matchers for ordering comparisons.
assert_that 1, greater_than(0)assert_that 2, less_than(3)assert_that 3, greater_or_equal_to(3)assert_that 4, less_or_equal_to(4) Ramcrest::EqualTo - Equality (via == ).
assert_that "my value", equal_to("my value") Ramcrest::HasAttribute - Object attribute matching.
dance = Struct.new(:twist).new(2)assert_that dance, has_attribute(:funk) # the attribute exitsassert_that dance, has_attribute(:funk, equal_to(2)) # the attribute exists with a value Ramcrest::HasSize - Collection size.
assert_that [1, 2], has_size(2)assert_that { :a => 1 }, has_size(less_or_equal_to(3)) Ramcrest::Includes - Enumerable inclusion.
assert_that [1, 2, 3], includes(2, 3)assert_that [6, 7, 2], includes(6, greater_than(6)) Ramcrest::IncludesExactly - Enumerable equality.
assert_that [1, 2, 3], includes_exactly(1, 2, 3)assert_that [3, 2, 1], aint(includes_exactly(1, 2, 3))assert_that [1], aint(includes_exactly(1, 2)) Ramcrest::IncludesInAnyOrderExactly - Enumerable set equality.
assert_that [2, 1, 3], includes_in_any_order_exactly(1, 2, 3)assert_that [1, 3, 4], aint(includes_in_any_order_exactly(1, 3)) Ramcrest::Is - Syntactic sugar for equality.
assert_that 1, is(1)assert_that 2, is(greater_than(1)) Ramcrest::SuchThat - Ad hoc matchers.
assert_that "my string", such_that do |value| value =~ /string/ ? success : mismatch("didn't contain 'string'")end Writing your own matchersThe simplest way to get started writing your own own matchers is to just makead-hoc matchers using such_that and chained match results. For example to puttogether a matcher for a certain type that has two properties you can simplydo: def a_token(with_attributes) name = has_attribute(:name, equal_to(with_attributes[:named])) string = has_attribute(:string, equal_to(with_attributes[:string])) description = "a token named <#{with_attributes[:named]}> with string <#{with_attributes[:string]}>" such_that(description) do |actual| name.matches?(actual).and_also { string.matches?(actual) } endend Using such_that should be able to allow you to write any matcher that youwant in a simple and straight-forward way. If you outgrow these kinds ofmatchers and want to move onto much larger possiblities, then you just need toimplement a class with two methods: matches?(actual) and descriptionf . Thematches? method needs to return either success or mismatch(description) . class AToken include Ramcrest::Matcher def initialize(name) @matchers = [Ramcrest::HasAttribute.has_attribute(:name, equal_to(name))] end def with_string(string) @matchers << Ramcrest::HasAttribute.has_attribute(:string, equal_to(string)) self end def matches?(actual) @matchers. collect { |matcher| matcher.matches?(actual) }. find(method(:success)) { |result| !result.matched? } end def description "a token that #{@matchers.collect(&:description).join(' and ')}" endenddef a_token_named(name) AToken.new(name)endassert_that something, is(a_token_named("foo").with_string("bar"))assert_that something_else, is(a_token_named("baz")) |
请发表评论