Stub

Replace an object with a stub object

Let's face it, creating stub objects is dead simple in Python. For example, a simple way to create a stub of foo is :

>>> def foo():
...     return 'foo'
>>> def newfoo():
...     return 'bar'
>>> oldfoo = foo
>>> try:
...     foo = newfoo
...     foo()
... finally:
...     foo = oldfoo
'bar'

With Stub , this is still possible, like so, and it doesn't save you much coding either:

>>> def foo():
...     return 'foo'
>>> def newfoo():
...     return 'bar'
>>> try:
...     foo = Stub(foo, replace=newfoo)
...     foo()
... finally:
...     foo = foo.restore()
'bar'

However, you can do more complex things too, like mimic sequential calls:

>>> def next_ingredient():
...     for i in ('eggs', 'flour'):
...         yield i
>>> orig_id = id(next_ingredient)
>>> next_ingredient = Stub(next_ingredient)
>>> def yeast():
...     return 'yeast'
>>> def butter():
...     return 'butter'
>>> try:
...     next_ingredient.replace([yeast, butter])
...     assert next_ingredient() == 'yeast'
...     assert next_ingredient() == 'butter'
...     next_ingredient()
... finally:
...     next_ingredient = next_ingredient.restore()
Traceback (most recent call last):
    ...
StopIteration
>>> assert id(next_ingredient) == orig_id

To accomplish this without Stub you would have to proxy a generator, which would be just a bit more coding.

In closing ... you probably don't need stub for simple stubbing but it might come in handy. The only reason I added it to testtools is because I had some tests that needed urlopen() to send a sequence of responses back in a test.


Methods

f __init__(self, fn, replace=<class testtools.stubs.NoValue at 0x7a4870>) ...

f __call__(self) ...

f replace(self, new) ...

Replace stub with an iterable of calls or a single callable

f restore(self) ...

returns original object for id

See the source for more information.