Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

An easy way to mock loosely defined Python dict objects

Is there an easy way to mock loosely defined dict objects in Python? For example, how can I easily express that given a dict input, I want to check whether or not each value in it conforms to a particular meta-definition, like minimum and maximum values, lengths, and types?

Being able to do this could be handy, for example, when writing tests.

In mock (unittest.mock in Python versions 3.3+) one can specify that a value can be ANY value, like in

>>> mock = Mock(return_value=None)
>>> mock('foo', bar=object())
>>> mock.assert_called_once_with('foo', bar=ANY)

However, what if bar above should be a dict-like object, like

>>> {'baz': <an integer between -3 and 14>, 'qux': <'yes' or 'no'>}
like image 279
Martin Thorsen Ranang Avatar asked Oct 11 '13 20:10

Martin Thorsen Ranang


1 Answers

I've actually written AnyValid, a minimal library that leverages the great work implemented in formencode and unittest.mock, to handle such cases.

For example, testing a dict object like described above, can then be expressed as

>>> from mock import Mock
>>> from any_valid import AnyValid, Int, OneOf
>>> valid_bar = {
...     'baz': AnyValid(Int(min=-3, max=14)),
...     'qux': AnyValid(OneOf(['yes', 'no'])),
...     }
>>> mock = Mock(return_value=None)
>>> mock('foo', bar={'baz': 4, 'qux': 'yes'})
>>> mock.assert_called_once_with('foo', bar=valid_bar)
>>>

Because AnyValid is can take any validator from the large set of validators in formencode, many other conditions can be specified in a similarly expressive manner.

like image 113
Martin Thorsen Ranang Avatar answered Sep 27 '22 17:09

Martin Thorsen Ranang