



Search — Stub 0.1 documentation

### Navigation

* [index](genindex.html "General Index")

* [Stub 0.1 documentation](index.html) »

Search

======

 Please activate JavaScript to enable the search

 functionality.

 

 From here you can search these documents. Enter your search

 words into the box below and click "search". Note that the search

 function will automatically search for all of the words. Pages

 containing fewer words won't appear in the result list.

 

### Navigation

* [index](genindex.html "General Index")

* [Stub 0.1 documentation](index.html) »

 © Copyright 2010-2011, the contributors.

 Last updated on Sep 22, 2013.

 Created using [Sphinx](http://sphinx.pocoo.org/) 1.1.3.

 

  

  

  

 #version\_menu, .rtd-badge.rtd {

 -webkit-transition: all 0.25s 0.75s;

 transition: all 0.25s 0.75s;

 }

 .footer\_popout:hover #version\_menu, .footer\_popout:hover .rtd-badge.rtd {

 -webkit-transition: all 0.25s 0s;

 transition: all 0.25s 0s;

 }

 .rtd-badge {

 position: fixed;

 display: block;

 bottom: 5px;

 height: 40px;

 text-indent: -9999em;

 border-radius: 3px;

 -moz-border-radius: 3px;

 -webkit-border-radius: 3px;

 box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 1px 0 rgba(255, 255, 255, 0.2) inset;

 -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 1px 0 rgba(255, 255, 255, 0.2) inset;

 -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 1px 0 rgba(255, 255, 255, 0.2) inset;

 }

 #version\_menu {

 position: fixed;

 visibility: hidden;

 opacity: 0;

 bottom: 11px;

 right: 47px;

 list-style-type: none;

 margin: 0;

 }

 .footer\_popout:hover #version\_menu {

 visibility: visible;

 opacity: 1;

 right: 166px;

 }

 #version\_menu li {

 display: block;

 float: right;

 }

 #version\_menu li a {

 display: block;

 padding: 6px 10px 4px 10px;

 margin: 7px 7px 0 0;

 font-weight: bold;

 font-size: 14px;

 height: 20px;

 line-height: 17px;

 text-decoration: none;

 color: #fff;

 background: #8ca1af url(//media.readthedocs.org//images/gradient-light.png) bottom left repeat-x;

 border-radius: 3px;

 -moz-border-radius: 3px;

 -webkit-border-radius: 3px;

 box-shadow: 0 1px 1px #465158;

 -moz-box-shadow: 0 1px 1px #465158;

 -webkit-box-shadow: 0 1px 1px #465158;

 text-shadow: 0 1px 1px rgba(0, 0, 0, 0.5);

 }

 #version\_menu li a:hover {

 text-decoration: none;

 background-color: #697983;

 box-shadow: 0 1px 0px #465158;

 -moz-box-shadow: 0 1px 0px #465158;

 -webkit-box-shadow: 0 1px 0px #465158;

 }

 .rtd-badge.rtd {

 background: #3b4449 url(//media.readthedocs.org//images/badge-rtd.png) scroll top left no-repeat;

 border: 1px solid #282E32;

 width: 41px;

 right: 5px;

 }

 .footer\_popout:hover .rtd-badge.rtd {

 width: 160px;

 }

 .rtd-badge.revsys { background: #465158 url(//media.readthedocs.org//images/badge-revsys.png) top left no-repeat;

 border: 1px solid #1C5871;

 width: 290px;

 right: 173px;

 }

 .rtd-badge.revsys-inline-sponsored {

 position: inherit;

 margin-left: auto;

 margin-right: 175px;

 margin-bottom: 5px;

 background: #465158 url(//media.readthedocs.org//images/badge-revsys.png) top left no-repeat;

 border: 1px solid #1C5871;

 width: 290px;

 right: 173px;

 }

 .rtd-badge.revsys-inline {

 position: inherit;

 margin-left: auto;

 margin-right: 175px;

 margin-bottom: 5px;

 background: #465158 url(//media.readthedocs.org//images/badge-revsys-sm.png) top left no-repeat;

 border: 1px solid #1C5871;

 width: 205px;

 right: 173px;

 }

 [Brought to you by Read the Docs](//readthedocs.org/projects/stub/?fromdocs=stub)

* [latest](/en/latest/)





Index — Stub 0.1 documentation

### Navigation

* [index](# "General Index")

* [Stub 0.1 documentation](index.html) »

Index

=====

### Quick search

 Enter search terms or a module, class or function name.

 

### Navigation

* [index](# "General Index")

* [Stub 0.1 documentation](index.html) »

 © Copyright 2010-2011, the contributors.

 Last updated on Sep 22, 2013.

 Created using [Sphinx](http://sphinx.pocoo.org/) 1.1.3.

 

  

  

  

 #version\_menu, .rtd-badge.rtd {

 -webkit-transition: all 0.25s 0.75s;

 transition: all 0.25s 0.75s;

 }

 .footer\_popout:hover #version\_menu, .footer\_popout:hover .rtd-badge.rtd {

 -webkit-transition: all 0.25s 0s;

 transition: all 0.25s 0s;

 }

 .rtd-badge {

 position: fixed;

 display: block;

 bottom: 5px;

 height: 40px;

 text-indent: -9999em;

 border-radius: 3px;

 -moz-border-radius: 3px;

 -webkit-border-radius: 3px;

 box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 1px 0 rgba(255, 255, 255, 0.2) inset;

 -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 1px 0 rgba(255, 255, 255, 0.2) inset;

 -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 1px 0 rgba(255, 255, 255, 0.2) inset;

 }

 #version\_menu {

 position: fixed;

 visibility: hidden;

 opacity: 0;

 bottom: 11px;

 right: 47px;

 list-style-type: none;

 margin: 0;

 }

 .footer\_popout:hover #version\_menu {

 visibility: visible;

 opacity: 1;

 right: 166px;

 }

 #version\_menu li {

 display: block;

 float: right;

 }

 #version\_menu li a {

 display: block;

 padding: 6px 10px 4px 10px;

 margin: 7px 7px 0 0;

 font-weight: bold;

 font-size: 14px;

 height: 20px;

 line-height: 17px;

 text-decoration: none;

 color: #fff;

 background: #8ca1af url(//media.readthedocs.org//images/gradient-light.png) bottom left repeat-x;

 border-radius: 3px;

 -moz-border-radius: 3px;

 -webkit-border-radius: 3px;

 box-shadow: 0 1px 1px #465158;

 -moz-box-shadow: 0 1px 1px #465158;

 -webkit-box-shadow: 0 1px 1px #465158;

 text-shadow: 0 1px 1px rgba(0, 0, 0, 0.5);

 }

 #version\_menu li a:hover {

 text-decoration: none;

 background-color: #697983;

 box-shadow: 0 1px 0px #465158;

 -moz-box-shadow: 0 1px 0px #465158;

 -webkit-box-shadow: 0 1px 0px #465158;

 }

 .rtd-badge.rtd {

 background: #3b4449 url(//media.readthedocs.org//images/badge-rtd.png) scroll top left no-repeat;

 border: 1px solid #282E32;

 width: 41px;

 right: 5px;

 }

 .footer\_popout:hover .rtd-badge.rtd {

 width: 160px;

 }

 .rtd-badge.revsys { background: #465158 url(//media.readthedocs.org//images/badge-revsys.png) top left no-repeat;

 border: 1px solid #1C5871;

 width: 290px;

 right: 173px;

 }

 .rtd-badge.revsys-inline-sponsored {

 position: inherit;

 margin-left: auto;

 margin-right: 175px;

 margin-bottom: 5px;

 background: #465158 url(//media.readthedocs.org//images/badge-revsys.png) top left no-repeat;

 border: 1px solid #1C5871;

 width: 290px;

 right: 173px;

 }

 .rtd-badge.revsys-inline {

 position: inherit;

 margin-left: auto;

 margin-right: 175px;

 margin-bottom: 5px;

 background: #465158 url(//media.readthedocs.org//images/badge-revsys-sm.png) top left no-repeat;

 border: 1px solid #1C5871;

 width: 205px;

 right: 173px;

 }

 [Brought to you by Read the Docs](//readthedocs.org/projects/stub/?fromdocs=stub)

* [latest](/en/latest/)





API Documentation — Stub 0.1 documentation

### Navigation

* [index](genindex.html "General Index")

* [next](stubvsmock.html "Stubbing vs. Mocking") |

* [previous](getting_started.html "Getting Started") |

* [Stub 0.1 documentation](index.html) »

API Documentation[¶](#api-documentation "Permalink to this headline")

=====================================================================

stub[¶](#stub "Permalink to this headline")

-------------------------------------------

stubbing[¶](#stubbing "Permalink to this headline")

---------------------------------------------------

### [Table Of Contents](index.html)

* [API Documentation](#)

	+ [stub](#stub)

	+ [stubbing](#stubbing)

#### Previous topic

[Getting Started](getting_started.html "previous chapter")

#### Next topic

[Stubbing vs. Mocking](stubvsmock.html "next chapter")

### This Page

* [Show Source](_sources/stubmodule.txt)

### Quick search

 Enter search terms or a module, class or function name.

 

### Navigation

* [index](genindex.html "General Index")

* [next](stubvsmock.html "Stubbing vs. Mocking") |

* [previous](getting_started.html "Getting Started") |

* [Stub 0.1 documentation](index.html) »

 © Copyright 2010-2011, the contributors.

 Last updated on Sep 22, 2013.

 Created using [Sphinx](http://sphinx.pocoo.org/) 1.1.3.

 

  

  

  

 #version\_menu, .rtd-badge.rtd {

 -webkit-transition: all 0.25s 0.75s;

 transition: all 0.25s 0.75s;

 }

 .footer\_popout:hover #version\_menu, .footer\_popout:hover .rtd-badge.rtd {

 -webkit-transition: all 0.25s 0s;

 transition: all 0.25s 0s;

 }

 .rtd-badge {

 position: fixed;

 display: block;

 bottom: 5px;

 height: 40px;

 text-indent: -9999em;

 border-radius: 3px;

 -moz-border-radius: 3px;

 -webkit-border-radius: 3px;

 box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 1px 0 rgba(255, 255, 255, 0.2) inset;

 -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 1px 0 rgba(255, 255, 255, 0.2) inset;

 -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 1px 0 rgba(255, 255, 255, 0.2) inset;

 }

 #version\_menu {

 position: fixed;

 visibility: hidden;

 opacity: 0;

 bottom: 11px;

 right: 47px;

 list-style-type: none;

 margin: 0;

 }

 .footer\_popout:hover #version\_menu {

 visibility: visible;

 opacity: 1;

 right: 166px;

 }

 #version\_menu li {

 display: block;

 float: right;

 }

 #version\_menu li a {

 display: block;

 padding: 6px 10px 4px 10px;

 margin: 7px 7px 0 0;

 font-weight: bold;

 font-size: 14px;

 height: 20px;

 line-height: 17px;

 text-decoration: none;

 color: #fff;

 background: #8ca1af url(//media.readthedocs.org//images/gradient-light.png) bottom left repeat-x;

 border-radius: 3px;

 -moz-border-radius: 3px;

 -webkit-border-radius: 3px;

 box-shadow: 0 1px 1px #465158;

 -moz-box-shadow: 0 1px 1px #465158;

 -webkit-box-shadow: 0 1px 1px #465158;

 text-shadow: 0 1px 1px rgba(0, 0, 0, 0.5);

 }

 #version\_menu li a:hover {

 text-decoration: none;

 background-color: #697983;

 box-shadow: 0 1px 0px #465158;

 -moz-box-shadow: 0 1px 0px #465158;

 -webkit-box-shadow: 0 1px 0px #465158;

 }

 .rtd-badge.rtd {

 background: #3b4449 url(//media.readthedocs.org//images/badge-rtd.png) scroll top left no-repeat;

 border: 1px solid #282E32;

 width: 41px;

 right: 5px;

 }

 .footer\_popout:hover .rtd-badge.rtd {

 width: 160px;

 }

 .rtd-badge.revsys { background: #465158 url(//media.readthedocs.org//images/badge-revsys.png) top left no-repeat;

 border: 1px solid #1C5871;

 width: 290px;

 right: 173px;

 }

 .rtd-badge.revsys-inline-sponsored {

 position: inherit;

 margin-left: auto;

 margin-right: 175px;

 margin-bottom: 5px;

 background: #465158 url(//media.readthedocs.org//images/badge-revsys.png) top left no-repeat;

 border: 1px solid #1C5871;

 width: 290px;

 right: 173px;

 }

 .rtd-badge.revsys-inline {

 position: inherit;

 margin-left: auto;

 margin-right: 175px;

 margin-bottom: 5px;

 background: #465158 url(//media.readthedocs.org//images/badge-revsys-sm.png) top left no-repeat;

 border: 1px solid #1C5871;

 width: 205px;

 right: 173px;

 }

 [Brought to you by Read the Docs](//readthedocs.org/projects/stub/?fromdocs=stub)

* [latest](/en/latest/)





Unit tests — Stub 0.1 documentation

### Navigation

* [index](genindex.html "General Index")

* [previous](stubvsmock.html "Stubbing vs. Mocking") |

* [Stub 0.1 documentation](index.html) »

Unit tests[¶](#unit-tests "Permalink to this headline")

=======================================================

stub is (of course) fully unit-tested. Run make test to run the full suite or make help for other test options.

#### Previous topic

[Stubbing vs. Mocking](stubvsmock.html "previous chapter")

### This Page

* [Show Source](_sources/tests_and_coverage.txt)

### Quick search

 Enter search terms or a module, class or function name.

 

### Navigation

* [index](genindex.html "General Index")

* [previous](stubvsmock.html "Stubbing vs. Mocking") |

* [Stub 0.1 documentation](index.html) »

 © Copyright 2010-2011, the contributors.

 Last updated on Sep 22, 2013.

 Created using [Sphinx](http://sphinx.pocoo.org/) 1.1.3.

 

  

  

  

 #version\_menu, .rtd-badge.rtd {

 -webkit-transition: all 0.25s 0.75s;

 transition: all 0.25s 0.75s;

 }

 .footer\_popout:hover #version\_menu, .footer\_popout:hover .rtd-badge.rtd {

 -webkit-transition: all 0.25s 0s;

 transition: all 0.25s 0s;

 }

 .rtd-badge {

 position: fixed;

 display: block;

 bottom: 5px;

 height: 40px;

 text-indent: -9999em;

 border-radius: 3px;

 -moz-border-radius: 3px;

 -webkit-border-radius: 3px;

 box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 1px 0 rgba(255, 255, 255, 0.2) inset;

 -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 1px 0 rgba(255, 255, 255, 0.2) inset;

 -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 1px 0 rgba(255, 255, 255, 0.2) inset;

 }

 #version\_menu {

 position: fixed;

 visibility: hidden;

 opacity: 0;

 bottom: 11px;

 right: 47px;

 list-style-type: none;

 margin: 0;

 }

 .footer\_popout:hover #version\_menu {

 visibility: visible;

 opacity: 1;

 right: 166px;

 }

 #version\_menu li {

 display: block;

 float: right;

 }

 #version\_menu li a {

 display: block;

 padding: 6px 10px 4px 10px;

 margin: 7px 7px 0 0;

 font-weight: bold;

 font-size: 14px;

 height: 20px;

 line-height: 17px;

 text-decoration: none;

 color: #fff;

 background: #8ca1af url(//media.readthedocs.org//images/gradient-light.png) bottom left repeat-x;

 border-radius: 3px;

 -moz-border-radius: 3px;

 -webkit-border-radius: 3px;

 box-shadow: 0 1px 1px #465158;

 -moz-box-shadow: 0 1px 1px #465158;

 -webkit-box-shadow: 0 1px 1px #465158;

 text-shadow: 0 1px 1px rgba(0, 0, 0, 0.5);

 }

 #version\_menu li a:hover {

 text-decoration: none;

 background-color: #697983;

 box-shadow: 0 1px 0px #465158;

 -moz-box-shadow: 0 1px 0px #465158;

 -webkit-box-shadow: 0 1px 0px #465158;

 }

 .rtd-badge.rtd {

 background: #3b4449 url(//media.readthedocs.org//images/badge-rtd.png) scroll top left no-repeat;

 border: 1px solid #282E32;

 width: 41px;

 right: 5px;

 }

 .footer\_popout:hover .rtd-badge.rtd {

 width: 160px;

 }

 .rtd-badge.revsys { background: #465158 url(//media.readthedocs.org//images/badge-revsys.png) top left no-repeat;

 border: 1px solid #1C5871;

 width: 290px;

 right: 173px;

 }

 .rtd-badge.revsys-inline-sponsored {

 position: inherit;

 margin-left: auto;

 margin-right: 175px;

 margin-bottom: 5px;

 background: #465158 url(//media.readthedocs.org//images/badge-revsys.png) top left no-repeat;

 border: 1px solid #1C5871;

 width: 290px;

 right: 173px;

 }

 .rtd-badge.revsys-inline {

 position: inherit;

 margin-left: auto;

 margin-right: 175px;

 margin-bottom: 5px;

 background: #465158 url(//media.readthedocs.org//images/badge-revsys-sm.png) top left no-repeat;

 border: 1px solid #1C5871;

 width: 205px;

 right: 173px;

 }

 [Brought to you by Read the Docs](//readthedocs.org/projects/stub/?fromdocs=stub)

* [latest](/en/latest/)





Getting Started — Stub 0.1 documentation

### Navigation

* [index](genindex.html "General Index")

* [next](stubmodule.html "API Documentation") |

* [previous](index.html "stub - a monkey-patcher on steroids") |

* [Stub 0.1 documentation](index.html) »

Getting Started[¶](#getting-started "Permalink to this headline")

=================================================================

The basic workhorse function of the stub library is stub.stub()

Stubbing Callables[¶](#stubbing-callables "Permalink to this headline")

-----------------------------------------------------------------------

The basic syntax for stubbing function behaviour is:

```

>>> from stub import stub

>>> target = lambda: 5 # This can be any callable object

>>> repl = lambda: 6 # This can also be any callable object

>>> f = stub(target, repl)

>>> target() # The target object now has the behaviour of the replacement object

6

```

Where target and repl are any callable objects. This function actually modifies the code of target in place, so all imports in other libraries automagically get the newest version of the stubbed-out behaviour.

### Stubbing a bound function[¶](#stubbing-a-bound-function "Permalink to this headline")

To stub out a bound function, call stub.stub() with the target and a replacement function:

```

>>> from stub import stub

>>> class A:

...     def f(self):

...         return 5

...

>>> repl = lambda x: 6

>>> a = A()

>>> a.f()

5

>>> f = stub(a.f, repl)

>>> a.f()

6

```

The stub.stub() function delegates to stub.stub\_bound\_function() when the target object is a bound function.

### Stubbing unbound functions[¶](#stubbing-unbound-functions "Permalink to this headline")

To stub an unbound function, call stub.stub(f, repl)() where f is the function

to stub and repl is the function with which to replace it.

```

>>> def f(x):

...   return x + 1

...

>>> import stub

>>> def f\_replacement(x):

...   return x + 2

...

>>> f(5)

6

>>> x = stub.stub(f, f\_replacement)

>>> f(5)

7

```

The stub.stub() function delegates to stub.stub\_unbound\_function() when the target object is an unbound function.

Stubbing Attribute Values[¶](#stubbing-attribute-values "Permalink to this headline")

-------------------------------------------------------------------------------------

To stub out attribute values call stub.stub() with new attribute values as keyword-arguments:

```

>>> from stub import stub

>>> class A(object):

...     def \_\_init\_\_(self):

...         self.x = 5

...

>>> a = A()

>>> a.x

5

>>> x = stub(a, x=10)

>>> a.x

10

```

The stub.stub() function delegates to stub.stub\_attributes() when called with keyword-arguments.

Unstubbing[¶](#unstubbing "Permalink to this headline")

-------------------------------------------------------

Once an attribute value or callable behaviour has been stubbed out, it can be useful to access the previous value or behaviour.

The unstubbed behaviour of a stubbed function f can be accessed calling the f.unstubbed() function:

```

>>> from stub import stub

>>> f = lambda: 5

>>> repl = lambda: 7

>>> x = stub(f, repl)

>>> f()

7

>>> f.unstubbed()

5

```

The unstubbed value of a stubbed attribute x on an object obj can be accessed by calling obj.x.unstubbed():

```

>>> from stub import stub

>>> class A(object):

...     def \_\_init\_\_(self):

...         self.x = 5

...

>>> a = A()

>>> a.x

5

>>> x = stub(a, x=7)

>>> a.x

7

>>> a.x.unstubbed()

5

```

To unstub a stubbed-out callable, target, call target.unstub():

```

>>> from stub import stub

>>> target = lambda: 5

>>> repl = lambda: 7

>>> x = stub(target, repl)

>>> target()

7

>>> target.unstub()

>>> target()

5

```

To unstub an individual attribute x on an object, target, call obj.x.unstub():

```

>>> from stub import stub

>>> class A(object):

...     def \_\_init\_\_(self):

...         self.x = 5

...

>>> a = A()

>>> x = stub(a, x=7)

>>> a.x

7

>>> a.x.unstub()

>>> a.x

5

```

To unstub all stubbed-out attributes on an object, target, call obj.unstub():

```

>>> from stub import stub

>>> class A(object):

...     def \_\_init\_\_(self):

...         self.x = 5

...         self.y = 7

...

>>> a = A()

>>> stub(a, x=7, y=10)

>>> a.x, a.y

(7, 10)

>>> a.unstub()

>>> a.x, a.y

(5, 7)

```

To unstub **all** stubbed-out functions and attributes, call stub.unstub\_all()

```

>>> from stub import stub, unstub\_all

>>> # Setup some base objects to stub

>>> class A(object):

...     def \_\_init\_\_(self):

...         self.x = 5

...         self.y = 7

...

>>> a = A()

>>> target = lambda: 5

>>> repl = lambda: 7

>>> # Stub out callable behaviour and object attributes

>>> stub(a, x=7, y=10)

>>> x = stub(target, repl)

>>> a.x, a.y, target() # Check that stubbing worked

(7, 10, 7)

>>> unstub\_all() # Unstub everything

>>> a.x, a.y, target() # Check that unstubbing worked

(5, 7, 5)

```

Warning

The stub.unstub\_all() function will affect **all** stubbed-out functions, methods and attributes **everywhere** in your current runtime. It is important also to **never** fiddle with stub.\_stubbed\_callables and stub.\_modified\_objects since these collections track stubbed-out objects.

### [Table Of Contents](index.html)

* [Getting Started](#)

	+ [Stubbing Callables](#stubbing-callables)

		- [Stubbing a bound function](#stubbing-a-bound-function)

		- [Stubbing unbound functions](#stubbing-unbound-functions)

	+ [Stubbing Attribute Values](#stubbing-attribute-values)

	+ [Unstubbing](#unstubbing)

#### Previous topic

[stub - a monkey-patcher on steroids](index.html "previous chapter")

#### Next topic

[API Documentation](stubmodule.html "next chapter")

### This Page

* [Show Source](_sources/getting_started.txt)

### Quick search

 Enter search terms or a module, class or function name.

 

### Navigation

* [index](genindex.html "General Index")

* [next](stubmodule.html "API Documentation") |

* [previous](index.html "stub - a monkey-patcher on steroids") |

* [Stub 0.1 documentation](index.html) »

 © Copyright 2010-2011, the contributors.

 Last updated on Sep 22, 2013.

 Created using [Sphinx](http://sphinx.pocoo.org/) 1.1.3.

 

  

  

  

 #version\_menu, .rtd-badge.rtd {

 -webkit-transition: all 0.25s 0.75s;

 transition: all 0.25s 0.75s;

 }

 .footer\_popout:hover #version\_menu, .footer\_popout:hover .rtd-badge.rtd {

 -webkit-transition: all 0.25s 0s;

 transition: all 0.25s 0s;

 }

 .rtd-badge {

 position: fixed;

 display: block;

 bottom: 5px;

 height: 40px;

 text-indent: -9999em;

 border-radius: 3px;

 -moz-border-radius: 3px;

 -webkit-border-radius: 3px;

 box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 1px 0 rgba(255, 255, 255, 0.2) inset;

 -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 1px 0 rgba(255, 255, 255, 0.2) inset;

 -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 1px 0 rgba(255, 255, 255, 0.2) inset;

 }

 #version\_menu {

 position: fixed;

 visibility: hidden;

 opacity: 0;

 bottom: 11px;

 right: 47px;

 list-style-type: none;

 margin: 0;

 }

 .footer\_popout:hover #version\_menu {

 visibility: visible;

 opacity: 1;

 right: 166px;

 }

 #version\_menu li {

 display: block;

 float: right;

 }

 #version\_menu li a {

 display: block;

 padding: 6px 10px 4px 10px;

 margin: 7px 7px 0 0;

 font-weight: bold;

 font-size: 14px;

 height: 20px;

 line-height: 17px;

 text-decoration: none;

 color: #fff;

 background: #8ca1af url(//media.readthedocs.org//images/gradient-light.png) bottom left repeat-x;

 border-radius: 3px;

 -moz-border-radius: 3px;

 -webkit-border-radius: 3px;

 box-shadow: 0 1px 1px #465158;

 -moz-box-shadow: 0 1px 1px #465158;

 -webkit-box-shadow: 0 1px 1px #465158;

 text-shadow: 0 1px 1px rgba(0, 0, 0, 0.5);

 }

 #version\_menu li a:hover {

 text-decoration: none;

 background-color: #697983;

 box-shadow: 0 1px 0px #465158;

 -moz-box-shadow: 0 1px 0px #465158;

 -webkit-box-shadow: 0 1px 0px #465158;

 }

 .rtd-badge.rtd {

 background: #3b4449 url(//media.readthedocs.org//images/badge-rtd.png) scroll top left no-repeat;

 border: 1px solid #282E32;

 width: 41px;

 right: 5px;

 }

 .footer\_popout:hover .rtd-badge.rtd {

 width: 160px;

 }

 .rtd-badge.revsys { background: #465158 url(//media.readthedocs.org//images/badge-revsys.png) top left no-repeat;

 border: 1px solid #1C5871;

 width: 290px;

 right: 173px;

 }

 .rtd-badge.revsys-inline-sponsored {

 position: inherit;

 margin-left: auto;

 margin-right: 175px;

 margin-bottom: 5px;

 background: #465158 url(//media.readthedocs.org//images/badge-revsys.png) top left no-repeat;

 border: 1px solid #1C5871;

 width: 290px;

 right: 173px;

 }

 .rtd-badge.revsys-inline {

 position: inherit;

 margin-left: auto;

 margin-right: 175px;

 margin-bottom: 5px;

 background: #465158 url(//media.readthedocs.org//images/badge-revsys-sm.png) top left no-repeat;

 border: 1px solid #1C5871;

 width: 205px;

 right: 173px;

 }

 [Brought to you by Read the Docs](//readthedocs.org/projects/stub/?fromdocs=stub)

* [latest](/en/latest/)





Stubbing vs. Mocking — Stub 0.1 documentation

### Navigation

* [index](genindex.html "General Index")

* [next](tests_and_coverage.html "Unit tests") |

* [previous](stubmodule.html "API Documentation") |

* [Stub 0.1 documentation](index.html) »

Stubbing vs. Mocking[¶](#stubbing-vs-mocking "Permalink to this headline")

==========================================================================

We’ve done a lot of testing of Python systems over the past couple of years. The best approach we’ve found so far for replacing the behaviour of test objects at runtime is stubbing.

We’ve read a lot about mocking and even written mocking libraries for other languages. But there is something about the way that mocks need to be manipulated that feels distinctly un-Pythonic.

Unlike some other languages, Python allows you to access most of the internals of objects easily at runtime. Using this facility, we have developed the stub library to help with replacing functionality on functions and objects.

Separation of concerns[¶](#separation-of-concerns "Permalink to this headline")

-------------------------------------------------------------------------------

When you can modify objects and functions for testing purposes and confine those modifications to testing code, your production code becomes much cleaner and easier to read. You can do away with all the large if debug: blocks and keep everything clear and concise.

This problem is usually solved with complex type hierarchies providing levels of abstraction that allow developers to plug testing implementations into the pre-defined interface. What’s funny/sad about this is that it is pure duplication of effort. We already have an interface, it’s just that we need to hook into it. Most of the function definitions and current type hierarchies do not need to be further abstracted in order to support testing.

A prime example is database connector modules. Obviously, you expect this module to actually connect to a database. Equally obvious is the fact that you don’t want this module connecting to a database for every single one of it’s thousands of unit-tests. So most projects have an abstraction layer with an AbstractAccessor superclass that is then subclassed into MySQLAccessor and TestAccessor classes. This is not a terrible solution, but it *does* increase the cognitive overhead of dealing with the hot, or most common, path of execution.

When we write code that is clear in intention, it is easy to maintain and update. Each successive layer of abstraction we add makes this more difficult. So keeping the test code *completely* separate from the production code just makes sense.

This philosophy leads us to prefer code like this:

```

class MySQLAccessor:

        def __init__(self):

                pass

        def connect(self, user=None, pass=None, dbhost=None):

                do_something()

def myfunc(x):

        return do_something_real()

# module mylib_test

import stub

def myfunc_repl(x):

        return 5 + x

stub.stub(myfunc, myfunc_repl)

```

But while stubbing may seem easy when you look at replacing behaviour on instance objects, stubbing functional code turns out to be a whole ‘nother ball of wax...

But I *did* import it![¶](#but-i-did-import-it "Permalink to this headline")

----------------------------------------------------------------------------

One of the most frustrating things when testing is needing to replace the behaviour of a function from another module.

When the function is used in multiple places in the codebase and each place uses it’s own import statement, each namespace has a binding to the original

function so simple monkeypatching of the source module won’t help:

```

# Module module\_a

import mylib

do\_something(mylib.myfunc())

# Module module\_b

import mylib

do\_something\_else(mylib.myfunc())

# Module mylib

def myfunc():

        return do\_something\_we\_dont\_want()

```

In this example, the naive approach to replacing the implementation of mylib.myfunc is to monkeypatch the mylib module like so:

```

# Module mod\_mylib

import mylib

def myfunc\_repl():

        return do\_something\_desirable()

mylib.myfunc = myfunc\_repl

```

Unfortunately, this code must execute *before* the code in module\_a and module\_b or else they will get handles on the original myfunc before it’s definition is replaced. In order to update the code executed by all handles to the original myfunc it is necessary to modify the internal code object that the function object wraps. In this way, any modules that have already imported the function get the updated functionality.

The stub library handles this properly for both unbound functions and object methods. Allowing you to replace the above monkeypatching code with the following:

```

# Module mod\_mylib

import stub

import mylib

def myfunc\_repl():

        return do\_something\_desirable()

stub(mylib.myfunc, myfunc\_repl)

```

This code can run at any time regardless of imports into other modules and will correctly update the code of myfunc so that all handles execute the new instructions.

### [Table Of Contents](index.html)

* [Stubbing vs. Mocking](#)

	+ [Separation of concerns](#separation-of-concerns)

	+ [But I *did* import it!](#but-i-did-import-it)

#### Previous topic

[API Documentation](stubmodule.html "previous chapter")

#### Next topic

[Unit tests](tests_and_coverage.html "next chapter")

### This Page

* [Show Source](_sources/stubvsmock.txt)

### Quick search

 Enter search terms or a module, class or function name.

 

### Navigation

* [index](genindex.html "General Index")

* [next](tests_and_coverage.html "Unit tests") |

* [previous](stubmodule.html "API Documentation") |

* [Stub 0.1 documentation](index.html) »

 © Copyright 2010-2011, the contributors.

 Last updated on Sep 22, 2013.

 Created using [Sphinx](http://sphinx.pocoo.org/) 1.1.3.

 

  

  

  

 #version\_menu, .rtd-badge.rtd {

 -webkit-transition: all 0.25s 0.75s;

 transition: all 0.25s 0.75s;

 }

 .footer\_popout:hover #version\_menu, .footer\_popout:hover .rtd-badge.rtd {

 -webkit-transition: all 0.25s 0s;

 transition: all 0.25s 0s;

 }

 .rtd-badge {

 position: fixed;

 display: block;

 bottom: 5px;

 height: 40px;

 text-indent: -9999em;

 border-radius: 3px;

 -moz-border-radius: 3px;

 -webkit-border-radius: 3px;

 box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 1px 0 rgba(255, 255, 255, 0.2) inset;

 -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 1px 0 rgba(255, 255, 255, 0.2) inset;

 -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 1px 0 rgba(255, 255, 255, 0.2) inset;

 }

 #version\_menu {

 position: fixed;

 visibility: hidden;

 opacity: 0;

 bottom: 11px;

 right: 47px;

 list-style-type: none;

 margin: 0;

 }

 .footer\_popout:hover #version\_menu {

 visibility: visible;

 opacity: 1;

 right: 166px;

 }

 #version\_menu li {

 display: block;

 float: right;

 }

 #version\_menu li a {

 display: block;

 padding: 6px 10px 4px 10px;

 margin: 7px 7px 0 0;

 font-weight: bold;

 font-size: 14px;

 height: 20px;

 line-height: 17px;

 text-decoration: none;

 color: #fff;

 background: #8ca1af url(//media.readthedocs.org//images/gradient-light.png) bottom left repeat-x;

 border-radius: 3px;

 -moz-border-radius: 3px;

 -webkit-border-radius: 3px;

 box-shadow: 0 1px 1px #465158;

 -moz-box-shadow: 0 1px 1px #465158;

 -webkit-box-shadow: 0 1px 1px #465158;

 text-shadow: 0 1px 1px rgba(0, 0, 0, 0.5);

 }

 #version\_menu li a:hover {

 text-decoration: none;

 background-color: #697983;

 box-shadow: 0 1px 0px #465158;

 -moz-box-shadow: 0 1px 0px #465158;

 -webkit-box-shadow: 0 1px 0px #465158;

 }

 .rtd-badge.rtd {

 background: #3b4449 url(//media.readthedocs.org//images/badge-rtd.png) scroll top left no-repeat;

 border: 1px solid #282E32;

 width: 41px;

 right: 5px;

 }

 .footer\_popout:hover .rtd-badge.rtd {

 width: 160px;

 }

 .rtd-badge.revsys { background: #465158 url(//media.readthedocs.org//images/badge-revsys.png) top left no-repeat;

 border: 1px solid #1C5871;

 width: 290px;

 right: 173px;

 }

 .rtd-badge.revsys-inline-sponsored {

 position: inherit;

 margin-left: auto;

 margin-right: 175px;

 margin-bottom: 5px;

 background: #465158 url(//media.readthedocs.org//images/badge-revsys.png) top left no-repeat;

 border: 1px solid #1C5871;

 width: 290px;

 right: 173px;

 }

 .rtd-badge.revsys-inline {

 position: inherit;

 margin-left: auto;

 margin-right: 175px;

 margin-bottom: 5px;

 background: #465158 url(//media.readthedocs.org//images/badge-revsys-sm.png) top left no-repeat;

 border: 1px solid #1C5871;

 width: 205px;

 right: 173px;

 }

 [Brought to you by Read the Docs](//readthedocs.org/projects/stub/?fromdocs=stub)

* [latest](/en/latest/)





stub - a monkey-patcher on steroids — Stub 0.1 documentation

### Navigation

* [index](genindex.html "General Index")

* [next](getting_started.html "Getting Started") |

* [Stub 0.1 documentation](#) »

stub - a monkey-patcher on steroids[¶](#stub-a-monkey-patcher-on-steroids "Permalink to this headline")

=======================================================================================================

> 

> *A method stub or simply stub in software development is a piece of code used to stand in for some other programming functionality. A stub may simulate the behavior of existing code (such as a procedure on a remote machine) or be a temporary substitute for yet-to-be-developed code. Stubs are therefore most useful in porting, distributed computing as well as general software development and testing.*

> 

> 

> —Wikipedia [[1]](#id2)

> 

> 

> 

The stub library allows you to temporarily replace the behaviour of callables and the value of attributes on objects.

Table of contents[¶](#table-of-contents "Permalink to this headline")

---------------------------------------------------------------------

* [Getting Started](getting_started.html)

	+ [Stubbing Callables](getting_started.html#stubbing-callables)

		- [Stubbing a bound function](getting_started.html#stubbing-a-bound-function)

		- [Stubbing unbound functions](getting_started.html#stubbing-unbound-functions)

	+ [Stubbing Attribute Values](getting_started.html#stubbing-attribute-values)

	+ [Unstubbing](getting_started.html#unstubbing)

* [API Documentation](stubmodule.html)

	+ [stub](stubmodule.html#stub)

	+ [stubbing](stubmodule.html#stubbing)

* [Stubbing vs. Mocking](stubvsmock.html)

	+ [Separation of concerns](stubvsmock.html#separation-of-concerns)

	+ [But I *did* import it!](stubvsmock.html#but-i-did-import-it)

* [Unit tests](tests_and_coverage.html)

---

| [[1]](#id1) | <http://en.wikipedia.org/wiki/Method_stub> |

### [Table Of Contents](#)

* [stub - a monkey-patcher on steroids](#)

	+ [Table of contents](#table-of-contents)

#### Next topic

[Getting Started](getting_started.html "next chapter")

### This Page

* [Show Source](_sources/index.txt)

### Quick search

 Enter search terms or a module, class or function name.

 

### Navigation

* [index](genindex.html "General Index")

* [next](getting_started.html "Getting Started") |

* [Stub 0.1 documentation](#) »

 © Copyright 2010-2011, the contributors.

 Last updated on Sep 22, 2013.

 Created using [Sphinx](http://sphinx.pocoo.org/) 1.1.3.

 

  

  

  

 #version\_menu, .rtd-badge.rtd {

 -webkit-transition: all 0.25s 0.75s;

 transition: all 0.25s 0.75s;

 }

 .footer\_popout:hover #version\_menu, .footer\_popout:hover .rtd-badge.rtd {

 -webkit-transition: all 0.25s 0s;

 transition: all 0.25s 0s;

 }

 .rtd-badge {

 position: fixed;

 display: block;

 bottom: 5px;

 height: 40px;

 text-indent: -9999em;

 border-radius: 3px;

 -moz-border-radius: 3px;

 -webkit-border-radius: 3px;

 box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 1px 0 rgba(255, 255, 255, 0.2) inset;

 -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 1px 0 rgba(255, 255, 255, 0.2) inset;

 -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 1px 0 rgba(255, 255, 255, 0.2) inset;

 }

 #version\_menu {

 position: fixed;

 visibility: hidden;

 opacity: 0;

 bottom: 11px;

 right: 47px;

 list-style-type: none;

 margin: 0;

 }

 .footer\_popout:hover #version\_menu {

 visibility: visible;

 opacity: 1;

 right: 166px;

 }

 #version\_menu li {

 display: block;

 float: right;

 }

 #version\_menu li a {

 display: block;

 padding: 6px 10px 4px 10px;

 margin: 7px 7px 0 0;

 font-weight: bold;

 font-size: 14px;

 height: 20px;

 line-height: 17px;

 text-decoration: none;

 color: #fff;

 background: #8ca1af url(//media.readthedocs.org//images/gradient-light.png) bottom left repeat-x;

 border-radius: 3px;

 -moz-border-radius: 3px;

 -webkit-border-radius: 3px;

 box-shadow: 0 1px 1px #465158;

 -moz-box-shadow: 0 1px 1px #465158;

 -webkit-box-shadow: 0 1px 1px #465158;

 text-shadow: 0 1px 1px rgba(0, 0, 0, 0.5);

 }

 #version\_menu li a:hover {

 text-decoration: none;

 background-color: #697983;

 box-shadow: 0 1px 0px #465158;

 -moz-box-shadow: 0 1px 0px #465158;

 -webkit-box-shadow: 0 1px 0px #465158;

 }

 .rtd-badge.rtd {

 background: #3b4449 url(//media.readthedocs.org//images/badge-rtd.png) scroll top left no-repeat;

 border: 1px solid #282E32;

 width: 41px;

 right: 5px;

 }

 .footer\_popout:hover .rtd-badge.rtd {

 width: 160px;

 }

 .rtd-badge.revsys { background: #465158 url(//media.readthedocs.org//images/badge-revsys.png) top left no-repeat;

 border: 1px solid #1C5871;

 width: 290px;

 right: 173px;

 }

 .rtd-badge.revsys-inline-sponsored {

 position: inherit;

 margin-left: auto;

 margin-right: 175px;

 margin-bottom: 5px;

 background: #465158 url(//media.readthedocs.org//images/badge-revsys.png) top left no-repeat;

 border: 1px solid #1C5871;

 width: 290px;

 right: 173px;

 }

 .rtd-badge.revsys-inline {

 position: inherit;

 margin-left: auto;

 margin-right: 175px;

 margin-bottom: 5px;

 background: #465158 url(//media.readthedocs.org//images/badge-revsys-sm.png) top left no-repeat;

 border: 1px solid #1C5871;

 width: 205px;

 right: 173px;

 }

 [Brought to you by Read the Docs](//readthedocs.org/projects/stub/?fromdocs=stub)

* [latest](/en/latest/)

