Back to Bazel

Mock Library Comparison¶

third_party/py/mock/html/compare.html

9.1.016.3 KB
Original Source

Mock Library Comparison

A side-by-side comparison of how to accomplish some basic tasks with mock and some other popular Python mocking libraries and frameworks.

These are:

Popular python mocking frameworks not yet represented here include MiniMock.

pMock (last release 2004 and doesn’t import in recent versions of Python) and python-mock (last release 2005) are intentionally omitted.

Note

A more up to date, and tested for all mock libraries (only the mock examples on this page can be executed as doctests) version of this comparison is maintained by Gary Bernhardt:

This comparison is by no means complete, and also may not be fully idiomatic for all the libraries represented. Please contribute corrections, missing comparisons, or comparisons for additional libraries to the mock issue tracker.

This comparison page was originally created by the Mox project and then extended for flexmock and mock by Herman Sheremetyev. Dingus examples written by Gary Bernhadt. fudge examples provided by Kumar McMillan.

Note

The examples tasks here were originally created by Mox which is a mocking framework rather than a library like mock. The tasks shown naturally exemplify tasks that frameworks are good at and not the ones they make harder. In particular you can take a Mock or MagicMock object and use it in any way you want with no up-front configuration. The same is also true for Dingus.

The examples for mock here assume version 0.7.0.

Simple fake object

\>\>\> # mock\>\>\> my\_mock=mock.Mock()\>\>\> my\_mock.some\_method.return\_value="calculated value"\>\>\> my\_mock.some\_attribute="value"\>\>\> assertEqual("calculated value",my\_mock.some\_method())\>\>\> assertEqual("value",my\_mock.some\_attribute)
# Flexmockmock=flexmock(some\_method=lambda:"calculated value",some\_attribute="value")assertEqual("calculated value",mock.some\_method())assertEqual("value",mock.some\_attribute)# Moxmock=mox.MockAnything()mock.some\_method().AndReturn("calculated value")mock.some\_attribute="value"mox.Replay(mock)assertEqual("calculated value",mock.some\_method())assertEqual("value",mock.some\_attribute)# Mockermock=mocker.mock()mock.some\_method()mocker.result("calculated value")mocker.replay()mock.some\_attribute="value"assertEqual("calculated value",mock.some\_method())assertEqual("value",mock.some\_attribute)
\>\>\> # Dingus\>\>\> my\_dingus=dingus.Dingus(some\_attribute="value",... some\_method\_\_returns="calculated value")\>\>\> assertEqual("calculated value",my\_dingus.some\_method())\>\>\> assertEqual("value",my\_dingus.some\_attribute)
\>\>\> # fudge\>\>\> my\_fake=(fudge.Fake()... .provides('some\_method')... .returns("calculated value")... .has\_attr(some\_attribute="value"))...\>\>\> assertEqual("calculated value",my\_fake.some\_method())\>\>\> assertEqual("value",my\_fake.some\_attribute)

Simple mock

\>\>\> # mock\>\>\> my\_mock=mock.Mock()\>\>\> my\_mock.some\_method.return\_value="value"\>\>\> assertEqual("value",my\_mock.some\_method())\>\>\> my\_mock.some\_method.assert\_called\_once\_with()
# Flexmockmock=flexmock()mock.should\_receive("some\_method").and\_return("value").onceassertEqual("value",mock.some\_method())# Moxmock=mox.MockAnything()mock.some\_method().AndReturn("value")mox.Replay(mock)assertEqual("value",mock.some\_method())mox.Verify(mock)# Mockermock=mocker.mock()mock.some\_method()mocker.result("value")mocker.replay()assertEqual("value",mock.some\_method())mocker.verify()
\>\>\> # Dingus\>\>\> my\_dingus=dingus.Dingus(some\_method\_\_returns="value")\>\>\> assertEqual("value",my\_dingus.some\_method())\>\>\> assertmy\_dingus.some\_method.calls().once()
\>\>\> # fudge\>\>\> @fudge.test... deftest():... my\_fake=(fudge.Fake()... .expects('some\_method')... .returns("value")... .times\_called(1))...\>\>\> test()Traceback (most recent call last):...AssertionError:fake:my\_fake.some\_method() was not called

Creating partial mocks

\>\>\> # mock\>\>\> SomeObject.some\_method=mock.Mock(return\_value='value')\>\>\> assertEqual("value",SomeObject.some\_method())
# Flexmockflexmock(SomeObject).should\_receive("some\_method").and\_return('value')assertEqual("value",mock.some\_method())# Moxmock=mox.MockObject(SomeObject)mock.some\_method().AndReturn("value")mox.Replay(mock)assertEqual("value",mock.some\_method())mox.Verify(mock)# Mockermock=mocker.mock(SomeObject)mock.Get()mocker.result("value")mocker.replay()assertEqual("value",mock.some\_method())mocker.verify()
\>\>\> # Dingus\>\>\> object=SomeObject\>\>\> object.some\_method=dingus.Dingus(return\_value="value")\>\>\> assertEqual("value",object.some\_method())
\>\>\> # fudge\>\>\> fake=fudge.Fake().is\_callable().returns("\<fudge-value\>")\>\>\> withfudge.patched\_context(SomeObject,'some\_method',fake):... s=SomeObject()... assertEqual("\<fudge-value\>",s.some\_method())...

Ensure calls are made in specific order

\>\>\> # mock\>\>\> my\_mock=mock.Mock(spec=SomeObject)\>\>\> my\_mock.method1()\<Mock name='mock.method1()' id='...'\>\>\>\> my\_mock.method2()\<Mock name='mock.method2()' id='...'\>\>\>\> assertEqual(my\_mock.mock\_calls,[call.method1(),call.method2()])
# Flexmockmock=flexmock(SomeObject)mock.should\_receive('method1').once.ordered.and\_return('first thing')mock.should\_receive('method2').once.ordered.and\_return('second thing')# Moxmock=mox.MockObject(SomeObject)mock.method1().AndReturn('first thing')mock.method2().AndReturn('second thing')mox.Replay(mock)mox.Verify(mock)# Mockermock=mocker.mock()withmocker.order():mock.method1()mocker.result('first thing')mock.method2()mocker.result('second thing')mocker.replay()mocker.verify()
\>\>\> # Dingus\>\>\> my\_dingus=dingus.Dingus()\>\>\> my\_dingus.method1()\<Dingus ...\>\>\>\> my\_dingus.method2()\<Dingus ...\>\>\>\> assertEqual(['method1','method2'],[call.nameforcallinmy\_dingus.calls])
\>\>\> # fudge\>\>\> @fudge.test... deftest():... my\_fake=(fudge.Fake()... .remember\_order()... .expects('method1')... .expects('method2'))... my\_fake.method2()... my\_fake.method1()...\>\>\> test()Traceback (most recent call last):...AssertionError: Call #1 was fake:my\_fake.method2(); Expected:#1 fake:my\_fake.method1(), #2 fake:my\_fake.method2(), end

Raising exceptions

\>\>\> # mock\>\>\> my\_mock=mock.Mock()\>\>\> my\_mock.some\_method.side\_effect=SomeException("message")\>\>\> assertRaises(SomeException,my\_mock.some\_method)
# Flexmockmock=flexmock()mock.should\_receive("some\_method").and\_raise(SomeException("message"))assertRaises(SomeException,mock.some\_method)# Moxmock=mox.MockAnything()mock.some\_method().AndRaise(SomeException("message"))mox.Replay(mock)assertRaises(SomeException,mock.some\_method)mox.Verify(mock)# Mockermock=mocker.mock()mock.some\_method()mocker.throw(SomeException("message"))mocker.replay()assertRaises(SomeException,mock.some\_method)mocker.verify()
\>\>\> # Dingus\>\>\> my\_dingus=dingus.Dingus()\>\>\> my\_dingus.some\_method=dingus.exception\_raiser(SomeException)\>\>\> assertRaises(SomeException,my\_dingus.some\_method)
\>\>\> # fudge\>\>\> my\_fake=(fudge.Fake()... .is\_callable()... .raises(SomeException("message")))...\>\>\> my\_fake()Traceback (most recent call last):...SomeException:message

Override new instances of a class

\>\>\> # mock\>\>\> withmock.patch('somemodule.Someclass')asMockClass:... MockClass.return\_value=some\_other\_object... assertEqual(some\_other\_object,somemodule.Someclass())...
# Flexmockflexmock(some\_module.SomeClass,new\_instances=some\_other\_object)assertEqual(some\_other\_object,some\_module.SomeClass())# Mox# (you will probably have mox.Mox() available as self.mox in a real test)mox.Mox().StubOutWithMock(some\_module,'SomeClass',use\_mock\_anything=True)some\_module.SomeClass().AndReturn(some\_other\_object)mox.ReplayAll()assertEqual(some\_other\_object,some\_module.SomeClass())# Mockerinstance=mocker.mock()klass=mocker.replace(SomeClass,spec=None)klass('expected','args')mocker.result(instance)
\>\>\> # Dingus\>\>\> MockClass=dingus.Dingus(return\_value=some\_other\_object)\>\>\> withdingus.patch('somemodule.SomeClass',MockClass):... assertEqual(some\_other\_object,somemodule.SomeClass())...
\>\>\> # fudge\>\>\> @fudge.patch('somemodule.SomeClass')... deftest(FakeClass):... FakeClass.is\_callable().returns(some\_other\_object)... assertEqual(some\_other\_object,somemodule.SomeClass())...\>\>\> test()

Call the same method multiple times

Note

You don’t need to do any configuration to call mock.Mock() methods multiple times. Attributes like call_count, call_args_list and method_calls provide various different ways of making assertions about how the mock was used.

\>\>\> # mock\>\>\> my\_mock=mock.Mock()\>\>\> my\_mock.some\_method()\<Mock name='mock.some\_method()' id='...'\>\>\>\> my\_mock.some\_method()\<Mock name='mock.some\_method()' id='...'\>\>\>\> assertmy\_mock.some\_method.call\_count\>=2
# Flexmock # (verifies that the method gets called at least twice)flexmock(some\_object).should\_receive('some\_method').at\_least.twice# Mox# (does not support variable number of calls, so you need to create a new entry for each explicit call)mock=mox.MockObject(some\_object)mock.some\_method(mox.IgnoreArg(),mox.IgnoreArg())mock.some\_method(mox.IgnoreArg(),mox.IgnoreArg())mox.Replay(mock)mox.Verify(mock)# Mocker# (TODO)
\>\>\> # Dingus\>\>\> my\_dingus=dingus.Dingus()\>\>\> my\_dingus.some\_method()\<Dingus ...\>\>\>\> my\_dingus.some\_method()\<Dingus ...\>\>\>\> assertlen(my\_dingus.calls('some\_method'))==2
\>\>\> # fudge\>\>\> @fudge.test... deftest():... my\_fake=fudge.Fake().expects('some\_method').times\_called(2)... my\_fake.some\_method()...\>\>\> test()Traceback (most recent call last):...AssertionError:fake:my\_fake.some\_method() was called 1 time(s). Expected 2.

Mock chained methods

\>\>\> # mock\>\>\> my\_mock=mock.Mock()\>\>\> method3=my\_mock.method1.return\_value.method2.return\_value.method3\>\>\> method3.return\_value='some value'\>\>\> assertEqual('some value',my\_mock.method1().method2().method3(1,2))\>\>\> method3.assert\_called\_once\_with(1,2)
# Flexmock# (intermediate method calls are automatically assigned to temporary fake objects# and can be called with any arguments)flexmock(some\_object).should\_receive('method1.method2.method3').with\_args(arg1,arg2).and\_return('some value')assertEqual('some\_value',some\_object.method1().method2().method3(arg1,arg2))
# Moxmock=mox.MockObject(some\_object)mock2=mox.MockAnything()mock3=mox.MockAnything()mock.method1().AndReturn(mock1)mock2.method2().AndReturn(mock2)mock3.method3(arg1,arg2).AndReturn('some\_value')self.mox.ReplayAll()assertEqual("some\_value",some\_object.method1().method2().method3(arg1,arg2))self.mox.VerifyAll()# Mocker# (TODO)
\>\>\> # Dingus\>\>\> my\_dingus=dingus.Dingus()\>\>\> method3=my\_dingus.method1.return\_value.method2.return\_value.method3\>\>\> method3.return\_value='some value'\>\>\> assertEqual('some value',my\_dingus.method1().method2().method3(1,2))\>\>\> assertmethod3.calls('()',1,2).once()
\>\>\> # fudge\>\>\> @fudge.test... deftest():... my\_fake=fudge.Fake()... (my\_fake... .expects('method1')... .returns\_fake()... .expects('method2')... .returns\_fake()... .expects('method3')... .with\_args(1,2)... .returns('some value'))... assertEqual('some value',my\_fake.method1().method2().method3(1,2))...\>\>\> test()

Mocking a context manager

Examples for mock, Dingus and fudge only (so far):

\>\>\> # mock\>\>\> my\_mock=mock.MagicMock()\>\>\> withmy\_mock:... pass...\>\>\> my\_mock.\_\_enter\_\_.assert\_called\_with()\>\>\> my\_mock.\_\_exit\_\_.assert\_called\_with(None,None,None)
\>\>\> # Dingus (nothing special here; all dinguses are "magic mocks")\>\>\> my\_dingus=dingus.Dingus()\>\>\> withmy\_dingus:... pass...\>\>\> assertmy\_dingus.\_\_enter\_\_.calls()\>\>\> assertmy\_dingus.\_\_exit\_\_.calls('()',None,None,None)
\>\>\> # fudge\>\>\> my\_fake=fudge.Fake().provides('\_\_enter\_\_').provides('\_\_exit\_\_')\>\>\> withmy\_fake:... pass...

Mocking the builtin open used as a context manager

Example for mock only (so far):

\>\>\> # mock\>\>\> my\_mock=mock.MagicMock()\>\>\> withmock.patch('\_\_builtin\_\_.open',my\_mock):... manager=my\_mock.return\_value.\_\_enter\_\_.return\_value... manager.read.return\_value='some data'... withopen('foo')ash:... data=h.read()...\>\>\> data'some data'\>\>\> my\_mock.assert\_called\_once\_with('foo')

or:

\>\>\> # mock\>\>\> withmock.patch('\_\_builtin\_\_.open')asmy\_mock:... my\_mock.return\_value.\_\_enter\_\_=lambdas:s... my\_mock.return\_value.\_\_exit\_\_=mock.Mock()... my\_mock.return\_value.read.return\_value='some data'... withopen('foo')ash:... data=h.read()...\>\>\> data'some data'\>\>\> my\_mock.assert\_called\_once\_with('foo')
\>\>\> # Dingus\>\>\> my\_dingus=dingus.Dingus()\>\>\> withdingus.patch('\_\_builtin\_\_.open',my\_dingus):... file\_=open.return\_value.\_\_enter\_\_.return\_value... file\_.read.return\_value='some data'... withopen('foo')ash:... data=f.read()...\>\>\> data'some data'\>\>\> assertmy\_dingus.calls('()','foo').once()
\>\>\> # fudge\>\>\> fromcontextlibimportcontextmanager\>\>\> fromStringIOimportStringIO\>\>\> @contextmanager... deffake\_file(filename):... yieldStringIO('sekrets')...\>\>\> withfudge.patch('\_\_builtin\_\_.open')asfake\_open:... fake\_open.is\_callable().calls(fake\_file)... withopen('/etc/password')asf:... data=f.read()...fake:\_\_builtin\_\_.open\>\>\> data'sekrets'

Table Of Contents

Previous topic

Further Examples

Next topic

CHANGELOG

This Page

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

© Copyright 2007-2012, Michael Foord & the mock team. Last updated on Nov 05, 2012. Created using Sphinx 1.1.3.