The last few weeks we have been working to improve pyDoubles matchers. Since v1.2, pyDoubles supports the open source library Hamcrest. The matchers allow you to check if your arguments meet certain characteristics. All matchers included in Hamcrest can be used with pyDoubles.
It is very simple to use them. In the next example we stub out the method “count_by_brand” so that it will return 120 if invoked with “bmw”, no matter the case of the input.:
cars_finder = stub(CarFinder())
when(cars_finder.count_by_brand).with_args(
    equal_to_ignoring_case(“bmw”)).then_return(120)

Hamcrest comes with a library of useful matchers. Here are some of the most important ones:

  • Core
    • anything – always matches, useful if you don’t care what the object under test is
    • describedAs – decorator to adding custom failure description
    • is – decorator to improve readability – see “Sugar”, below
  • Logical
    • allOf – matches if all matchers match, short circuits (like Java &&)
    • anyOf – matches if any matchers match, short circuits (like Java ||)
    • not – matches if the wrapped matcher doesn’t match and vice versa
  • Object
    • equalTo – test object equality using Object.equals
    • hasToString – test Object.toString
    • instanceOf, isCompatibleType – test type
    • notNullValue, nullValue – test for null
    • sameInstance – test object identity
  • Beans
    • hasProperty – test JavaBeans properties
  • Collections
    • array – test an array’s elements against an array of matchers
    • hasEntry, hasKey, hasValue – test a map contains an entry, key or value
    • hasItem, hasItems – test a collection contains elements
    • hasItemInArray – test an array contains an element
  • Number
    • closeTo – test floating point values are close to a given value
    • greaterThan, greaterThanOrEqualTo, lessThan, lessThanOrEqualTo – test ordering
  • Text
    • equalToIgnoringCase – test string equality ignoring case
    • equalToIgnoringWhiteSpace – test string equality ignoring differences in runs of whitespace
    • containsString, endsWith, startsWith – test string matching
If you can’t find the match that you need, you can program your own match. To work with pyDoubles just need to create a class that implements the following:
  • A method called “matches” that returns a boolean value and it receives a parameter to be checked.
  • Optionally, a constructor who gets what you need to make the match.
  • Optionally, define value to “matcher_name” which prints a descriptive message of your matches in pyDoubles messages.
For example, we will create a matcher that returns True if you receive a phone number in a particular format.
class IsTelephoneNumber(PyDoublesMatcher):
    matcher_name = "is telephone number"
    def __init__(self, format):
        self.defined_arg = format
    def matches(self, arg):
        return self._is_telephone_number_in_format(arg, self.defined_arg)

    def _is_telephone_number_in_format(self, telephone, format):
        .... assume this would implement some check...

With a little more work, you can support your matcher with pyDoubles and Hamcrest. You can find more information in the Hamcrest wiki.

The currently supported version of PyHamcrest is v1.5.

Finally, the method: “assert_that” as been renamed to “assert_that_method” to avoid conflicts with Hamcrest.

You can download the latest version of pyDoubles here: https://bitbucket.org/carlosble/pydoubles/downloads/