python/mock-1.0.0/docs/compare.txt

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 =========================
michael@0 2 Mock Library Comparison
michael@0 3 =========================
michael@0 4
michael@0 5
michael@0 6 .. testsetup::
michael@0 7
michael@0 8 def assertEqual(a, b):
michael@0 9 assert a == b, ("%r != %r" % (a, b))
michael@0 10
michael@0 11 def assertRaises(Exc, func):
michael@0 12 try:
michael@0 13 func()
michael@0 14 except Exc:
michael@0 15 return
michael@0 16 assert False, ("%s not raised" % Exc)
michael@0 17
michael@0 18 sys.modules['somemodule'] = somemodule = mock.Mock(name='somemodule')
michael@0 19 class SomeException(Exception):
michael@0 20 some_method = method1 = method2 = None
michael@0 21 some_other_object = SomeObject = SomeException
michael@0 22
michael@0 23
michael@0 24 A side-by-side comparison of how to accomplish some basic tasks with mock and
michael@0 25 some other popular Python mocking libraries and frameworks.
michael@0 26
michael@0 27 These are:
michael@0 28
michael@0 29 * `flexmock <http://pypi.python.org/pypi/flexmock>`_
michael@0 30 * `mox <http://pypi.python.org/pypi/mox>`_
michael@0 31 * `Mocker <http://niemeyer.net/mocker>`_
michael@0 32 * `dingus <http://pypi.python.org/pypi/dingus>`_
michael@0 33 * `fudge <http://pypi.python.org/pypi/fudge>`_
michael@0 34
michael@0 35 Popular python mocking frameworks not yet represented here include
michael@0 36 `MiniMock <http://pypi.python.org/pypi/MiniMock>`_.
michael@0 37
michael@0 38 `pMock <http://pmock.sourceforge.net/>`_ (last release 2004 and doesn't import
michael@0 39 in recent versions of Python) and
michael@0 40 `python-mock <http://python-mock.sourceforge.net/>`_ (last release 2005) are
michael@0 41 intentionally omitted.
michael@0 42
michael@0 43 .. note::
michael@0 44
michael@0 45 A more up to date, and tested for all mock libraries (only the mock
michael@0 46 examples on this page can be executed as doctests) version of this
michael@0 47 comparison is maintained by Gary Bernhardt:
michael@0 48
michael@0 49 * `Python Mock Library Comparison
michael@0 50 <http://garybernhardt.github.com/python-mock-comparison/>`_
michael@0 51
michael@0 52 This comparison is by no means complete, and also may not be fully idiomatic
michael@0 53 for all the libraries represented. *Please* contribute corrections, missing
michael@0 54 comparisons, or comparisons for additional libraries to the `mock issue
michael@0 55 tracker <https://code.google.com/p/mock/issues/list>`_.
michael@0 56
michael@0 57 This comparison page was originally created by the `Mox project
michael@0 58 <https://code.google.com/p/pymox/wiki/MoxComparison>`_ and then extended for
michael@0 59 `flexmock and mock <http://has207.github.com/flexmock/compare.html>`_ by
michael@0 60 Herman Sheremetyev. Dingus examples written by `Gary Bernhadt
michael@0 61 <http://garybernhardt.github.com/python-mock-comparison/>`_. fudge examples
michael@0 62 provided by `Kumar McMillan <http://farmdev.com/>`_.
michael@0 63
michael@0 64 .. note::
michael@0 65
michael@0 66 The examples tasks here were originally created by Mox which is a mocking
michael@0 67 *framework* rather than a library like mock. The tasks shown naturally
michael@0 68 exemplify tasks that frameworks are good at and not the ones they make
michael@0 69 harder. In particular you can take a `Mock` or `MagicMock` object and use
michael@0 70 it in any way you want with no up-front configuration. The same is also
michael@0 71 true for Dingus.
michael@0 72
michael@0 73 The examples for mock here assume version 0.7.0.
michael@0 74
michael@0 75
michael@0 76 Simple fake object
michael@0 77 ~~~~~~~~~~~~~~~~~~
michael@0 78
michael@0 79 .. doctest::
michael@0 80
michael@0 81 >>> # mock
michael@0 82 >>> my_mock = mock.Mock()
michael@0 83 >>> my_mock.some_method.return_value = "calculated value"
michael@0 84 >>> my_mock.some_attribute = "value"
michael@0 85 >>> assertEqual("calculated value", my_mock.some_method())
michael@0 86 >>> assertEqual("value", my_mock.some_attribute)
michael@0 87
michael@0 88 ::
michael@0 89
michael@0 90 # Flexmock
michael@0 91 mock = flexmock(some_method=lambda: "calculated value", some_attribute="value")
michael@0 92 assertEqual("calculated value", mock.some_method())
michael@0 93 assertEqual("value", mock.some_attribute)
michael@0 94
michael@0 95 # Mox
michael@0 96 mock = mox.MockAnything()
michael@0 97 mock.some_method().AndReturn("calculated value")
michael@0 98 mock.some_attribute = "value"
michael@0 99 mox.Replay(mock)
michael@0 100 assertEqual("calculated value", mock.some_method())
michael@0 101 assertEqual("value", mock.some_attribute)
michael@0 102
michael@0 103 # Mocker
michael@0 104 mock = mocker.mock()
michael@0 105 mock.some_method()
michael@0 106 mocker.result("calculated value")
michael@0 107 mocker.replay()
michael@0 108 mock.some_attribute = "value"
michael@0 109 assertEqual("calculated value", mock.some_method())
michael@0 110 assertEqual("value", mock.some_attribute)
michael@0 111
michael@0 112 ::
michael@0 113
michael@0 114 >>> # Dingus
michael@0 115 >>> my_dingus = dingus.Dingus(some_attribute="value",
michael@0 116 ... some_method__returns="calculated value")
michael@0 117 >>> assertEqual("calculated value", my_dingus.some_method())
michael@0 118 >>> assertEqual("value", my_dingus.some_attribute)
michael@0 119
michael@0 120 ::
michael@0 121
michael@0 122 >>> # fudge
michael@0 123 >>> my_fake = (fudge.Fake()
michael@0 124 ... .provides('some_method')
michael@0 125 ... .returns("calculated value")
michael@0 126 ... .has_attr(some_attribute="value"))
michael@0 127 ...
michael@0 128 >>> assertEqual("calculated value", my_fake.some_method())
michael@0 129 >>> assertEqual("value", my_fake.some_attribute)
michael@0 130
michael@0 131
michael@0 132 Simple mock
michael@0 133 ~~~~~~~~~~~
michael@0 134
michael@0 135 .. doctest::
michael@0 136
michael@0 137 >>> # mock
michael@0 138 >>> my_mock = mock.Mock()
michael@0 139 >>> my_mock.some_method.return_value = "value"
michael@0 140 >>> assertEqual("value", my_mock.some_method())
michael@0 141 >>> my_mock.some_method.assert_called_once_with()
michael@0 142
michael@0 143 ::
michael@0 144
michael@0 145 # Flexmock
michael@0 146 mock = flexmock()
michael@0 147 mock.should_receive("some_method").and_return("value").once
michael@0 148 assertEqual("value", mock.some_method())
michael@0 149
michael@0 150 # Mox
michael@0 151 mock = mox.MockAnything()
michael@0 152 mock.some_method().AndReturn("value")
michael@0 153 mox.Replay(mock)
michael@0 154 assertEqual("value", mock.some_method())
michael@0 155 mox.Verify(mock)
michael@0 156
michael@0 157 # Mocker
michael@0 158 mock = mocker.mock()
michael@0 159 mock.some_method()
michael@0 160 mocker.result("value")
michael@0 161 mocker.replay()
michael@0 162 assertEqual("value", mock.some_method())
michael@0 163 mocker.verify()
michael@0 164
michael@0 165 ::
michael@0 166
michael@0 167 >>> # Dingus
michael@0 168 >>> my_dingus = dingus.Dingus(some_method__returns="value")
michael@0 169 >>> assertEqual("value", my_dingus.some_method())
michael@0 170 >>> assert my_dingus.some_method.calls().once()
michael@0 171
michael@0 172 ::
michael@0 173
michael@0 174 >>> # fudge
michael@0 175 >>> @fudge.test
michael@0 176 ... def test():
michael@0 177 ... my_fake = (fudge.Fake()
michael@0 178 ... .expects('some_method')
michael@0 179 ... .returns("value")
michael@0 180 ... .times_called(1))
michael@0 181 ...
michael@0 182 >>> test()
michael@0 183 Traceback (most recent call last):
michael@0 184 ...
michael@0 185 AssertionError: fake:my_fake.some_method() was not called
michael@0 186
michael@0 187
michael@0 188 Creating partial mocks
michael@0 189 ~~~~~~~~~~~~~~~~~~~~~~
michael@0 190
michael@0 191 .. doctest::
michael@0 192
michael@0 193 >>> # mock
michael@0 194 >>> SomeObject.some_method = mock.Mock(return_value='value')
michael@0 195 >>> assertEqual("value", SomeObject.some_method())
michael@0 196
michael@0 197 ::
michael@0 198
michael@0 199 # Flexmock
michael@0 200 flexmock(SomeObject).should_receive("some_method").and_return('value')
michael@0 201 assertEqual("value", mock.some_method())
michael@0 202
michael@0 203 # Mox
michael@0 204 mock = mox.MockObject(SomeObject)
michael@0 205 mock.some_method().AndReturn("value")
michael@0 206 mox.Replay(mock)
michael@0 207 assertEqual("value", mock.some_method())
michael@0 208 mox.Verify(mock)
michael@0 209
michael@0 210 # Mocker
michael@0 211 mock = mocker.mock(SomeObject)
michael@0 212 mock.Get()
michael@0 213 mocker.result("value")
michael@0 214 mocker.replay()
michael@0 215 assertEqual("value", mock.some_method())
michael@0 216 mocker.verify()
michael@0 217
michael@0 218 ::
michael@0 219
michael@0 220 >>> # Dingus
michael@0 221 >>> object = SomeObject
michael@0 222 >>> object.some_method = dingus.Dingus(return_value="value")
michael@0 223 >>> assertEqual("value", object.some_method())
michael@0 224
michael@0 225 ::
michael@0 226
michael@0 227 >>> # fudge
michael@0 228 >>> fake = fudge.Fake().is_callable().returns("<fudge-value>")
michael@0 229 >>> with fudge.patched_context(SomeObject, 'some_method', fake):
michael@0 230 ... s = SomeObject()
michael@0 231 ... assertEqual("<fudge-value>", s.some_method())
michael@0 232 ...
michael@0 233
michael@0 234
michael@0 235 Ensure calls are made in specific order
michael@0 236 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
michael@0 237
michael@0 238 .. doctest::
michael@0 239
michael@0 240 >>> # mock
michael@0 241 >>> my_mock = mock.Mock(spec=SomeObject)
michael@0 242 >>> my_mock.method1()
michael@0 243 <Mock name='mock.method1()' id='...'>
michael@0 244 >>> my_mock.method2()
michael@0 245 <Mock name='mock.method2()' id='...'>
michael@0 246 >>> assertEqual(my_mock.mock_calls, [call.method1(), call.method2()])
michael@0 247
michael@0 248 ::
michael@0 249
michael@0 250 # Flexmock
michael@0 251 mock = flexmock(SomeObject)
michael@0 252 mock.should_receive('method1').once.ordered.and_return('first thing')
michael@0 253 mock.should_receive('method2').once.ordered.and_return('second thing')
michael@0 254
michael@0 255 # Mox
michael@0 256 mock = mox.MockObject(SomeObject)
michael@0 257 mock.method1().AndReturn('first thing')
michael@0 258 mock.method2().AndReturn('second thing')
michael@0 259 mox.Replay(mock)
michael@0 260 mox.Verify(mock)
michael@0 261
michael@0 262 # Mocker
michael@0 263 mock = mocker.mock()
michael@0 264 with mocker.order():
michael@0 265 mock.method1()
michael@0 266 mocker.result('first thing')
michael@0 267 mock.method2()
michael@0 268 mocker.result('second thing')
michael@0 269 mocker.replay()
michael@0 270 mocker.verify()
michael@0 271
michael@0 272 ::
michael@0 273
michael@0 274 >>> # Dingus
michael@0 275 >>> my_dingus = dingus.Dingus()
michael@0 276 >>> my_dingus.method1()
michael@0 277 <Dingus ...>
michael@0 278 >>> my_dingus.method2()
michael@0 279 <Dingus ...>
michael@0 280 >>> assertEqual(['method1', 'method2'], [call.name for call in my_dingus.calls])
michael@0 281
michael@0 282 ::
michael@0 283
michael@0 284 >>> # fudge
michael@0 285 >>> @fudge.test
michael@0 286 ... def test():
michael@0 287 ... my_fake = (fudge.Fake()
michael@0 288 ... .remember_order()
michael@0 289 ... .expects('method1')
michael@0 290 ... .expects('method2'))
michael@0 291 ... my_fake.method2()
michael@0 292 ... my_fake.method1()
michael@0 293 ...
michael@0 294 >>> test()
michael@0 295 Traceback (most recent call last):
michael@0 296 ...
michael@0 297 AssertionError: Call #1 was fake:my_fake.method2(); Expected: #1 fake:my_fake.method1(), #2 fake:my_fake.method2(), end
michael@0 298
michael@0 299
michael@0 300 Raising exceptions
michael@0 301 ~~~~~~~~~~~~~~~~~~
michael@0 302
michael@0 303 .. doctest::
michael@0 304
michael@0 305 >>> # mock
michael@0 306 >>> my_mock = mock.Mock()
michael@0 307 >>> my_mock.some_method.side_effect = SomeException("message")
michael@0 308 >>> assertRaises(SomeException, my_mock.some_method)
michael@0 309
michael@0 310 ::
michael@0 311
michael@0 312 # Flexmock
michael@0 313 mock = flexmock()
michael@0 314 mock.should_receive("some_method").and_raise(SomeException("message"))
michael@0 315 assertRaises(SomeException, mock.some_method)
michael@0 316
michael@0 317 # Mox
michael@0 318 mock = mox.MockAnything()
michael@0 319 mock.some_method().AndRaise(SomeException("message"))
michael@0 320 mox.Replay(mock)
michael@0 321 assertRaises(SomeException, mock.some_method)
michael@0 322 mox.Verify(mock)
michael@0 323
michael@0 324 # Mocker
michael@0 325 mock = mocker.mock()
michael@0 326 mock.some_method()
michael@0 327 mocker.throw(SomeException("message"))
michael@0 328 mocker.replay()
michael@0 329 assertRaises(SomeException, mock.some_method)
michael@0 330 mocker.verify()
michael@0 331
michael@0 332 ::
michael@0 333
michael@0 334 >>> # Dingus
michael@0 335 >>> my_dingus = dingus.Dingus()
michael@0 336 >>> my_dingus.some_method = dingus.exception_raiser(SomeException)
michael@0 337 >>> assertRaises(SomeException, my_dingus.some_method)
michael@0 338
michael@0 339 ::
michael@0 340
michael@0 341 >>> # fudge
michael@0 342 >>> my_fake = (fudge.Fake()
michael@0 343 ... .is_callable()
michael@0 344 ... .raises(SomeException("message")))
michael@0 345 ...
michael@0 346 >>> my_fake()
michael@0 347 Traceback (most recent call last):
michael@0 348 ...
michael@0 349 SomeException: message
michael@0 350
michael@0 351
michael@0 352 Override new instances of a class
michael@0 353 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
michael@0 354
michael@0 355 .. doctest::
michael@0 356
michael@0 357 >>> # mock
michael@0 358 >>> with mock.patch('somemodule.Someclass') as MockClass:
michael@0 359 ... MockClass.return_value = some_other_object
michael@0 360 ... assertEqual(some_other_object, somemodule.Someclass())
michael@0 361 ...
michael@0 362
michael@0 363
michael@0 364 ::
michael@0 365
michael@0 366 # Flexmock
michael@0 367 flexmock(some_module.SomeClass, new_instances=some_other_object)
michael@0 368 assertEqual(some_other_object, some_module.SomeClass())
michael@0 369
michael@0 370 # Mox
michael@0 371 # (you will probably have mox.Mox() available as self.mox in a real test)
michael@0 372 mox.Mox().StubOutWithMock(some_module, 'SomeClass', use_mock_anything=True)
michael@0 373 some_module.SomeClass().AndReturn(some_other_object)
michael@0 374 mox.ReplayAll()
michael@0 375 assertEqual(some_other_object, some_module.SomeClass())
michael@0 376
michael@0 377 # Mocker
michael@0 378 instance = mocker.mock()
michael@0 379 klass = mocker.replace(SomeClass, spec=None)
michael@0 380 klass('expected', 'args')
michael@0 381 mocker.result(instance)
michael@0 382
michael@0 383 ::
michael@0 384
michael@0 385 >>> # Dingus
michael@0 386 >>> MockClass = dingus.Dingus(return_value=some_other_object)
michael@0 387 >>> with dingus.patch('somemodule.SomeClass', MockClass):
michael@0 388 ... assertEqual(some_other_object, somemodule.SomeClass())
michael@0 389 ...
michael@0 390
michael@0 391 ::
michael@0 392
michael@0 393 >>> # fudge
michael@0 394 >>> @fudge.patch('somemodule.SomeClass')
michael@0 395 ... def test(FakeClass):
michael@0 396 ... FakeClass.is_callable().returns(some_other_object)
michael@0 397 ... assertEqual(some_other_object, somemodule.SomeClass())
michael@0 398 ...
michael@0 399 >>> test()
michael@0 400
michael@0 401
michael@0 402 Call the same method multiple times
michael@0 403 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
michael@0 404
michael@0 405 .. note::
michael@0 406
michael@0 407 You don't need to do *any* configuration to call `mock.Mock()` methods
michael@0 408 multiple times. Attributes like `call_count`, `call_args_list` and
michael@0 409 `method_calls` provide various different ways of making assertions about
michael@0 410 how the mock was used.
michael@0 411
michael@0 412 .. doctest::
michael@0 413
michael@0 414 >>> # mock
michael@0 415 >>> my_mock = mock.Mock()
michael@0 416 >>> my_mock.some_method()
michael@0 417 <Mock name='mock.some_method()' id='...'>
michael@0 418 >>> my_mock.some_method()
michael@0 419 <Mock name='mock.some_method()' id='...'>
michael@0 420 >>> assert my_mock.some_method.call_count >= 2
michael@0 421
michael@0 422 ::
michael@0 423
michael@0 424 # Flexmock # (verifies that the method gets called at least twice)
michael@0 425 flexmock(some_object).should_receive('some_method').at_least.twice
michael@0 426
michael@0 427 # Mox
michael@0 428 # (does not support variable number of calls, so you need to create a new entry for each explicit call)
michael@0 429 mock = mox.MockObject(some_object)
michael@0 430 mock.some_method(mox.IgnoreArg(), mox.IgnoreArg())
michael@0 431 mock.some_method(mox.IgnoreArg(), mox.IgnoreArg())
michael@0 432 mox.Replay(mock)
michael@0 433 mox.Verify(mock)
michael@0 434
michael@0 435 # Mocker
michael@0 436 # (TODO)
michael@0 437
michael@0 438 ::
michael@0 439
michael@0 440 >>> # Dingus
michael@0 441 >>> my_dingus = dingus.Dingus()
michael@0 442 >>> my_dingus.some_method()
michael@0 443 <Dingus ...>
michael@0 444 >>> my_dingus.some_method()
michael@0 445 <Dingus ...>
michael@0 446 >>> assert len(my_dingus.calls('some_method')) == 2
michael@0 447
michael@0 448 ::
michael@0 449
michael@0 450 >>> # fudge
michael@0 451 >>> @fudge.test
michael@0 452 ... def test():
michael@0 453 ... my_fake = fudge.Fake().expects('some_method').times_called(2)
michael@0 454 ... my_fake.some_method()
michael@0 455 ...
michael@0 456 >>> test()
michael@0 457 Traceback (most recent call last):
michael@0 458 ...
michael@0 459 AssertionError: fake:my_fake.some_method() was called 1 time(s). Expected 2.
michael@0 460
michael@0 461
michael@0 462 Mock chained methods
michael@0 463 ~~~~~~~~~~~~~~~~~~~~
michael@0 464
michael@0 465 .. doctest::
michael@0 466
michael@0 467 >>> # mock
michael@0 468 >>> my_mock = mock.Mock()
michael@0 469 >>> method3 = my_mock.method1.return_value.method2.return_value.method3
michael@0 470 >>> method3.return_value = 'some value'
michael@0 471 >>> assertEqual('some value', my_mock.method1().method2().method3(1, 2))
michael@0 472 >>> method3.assert_called_once_with(1, 2)
michael@0 473
michael@0 474 ::
michael@0 475
michael@0 476 # Flexmock
michael@0 477 # (intermediate method calls are automatically assigned to temporary fake objects
michael@0 478 # and can be called with any arguments)
michael@0 479 flexmock(some_object).should_receive(
michael@0 480 'method1.method2.method3'
michael@0 481 ).with_args(arg1, arg2).and_return('some value')
michael@0 482 assertEqual('some_value', some_object.method1().method2().method3(arg1, arg2))
michael@0 483
michael@0 484 ::
michael@0 485
michael@0 486 # Mox
michael@0 487 mock = mox.MockObject(some_object)
michael@0 488 mock2 = mox.MockAnything()
michael@0 489 mock3 = mox.MockAnything()
michael@0 490 mock.method1().AndReturn(mock1)
michael@0 491 mock2.method2().AndReturn(mock2)
michael@0 492 mock3.method3(arg1, arg2).AndReturn('some_value')
michael@0 493 self.mox.ReplayAll()
michael@0 494 assertEqual("some_value", some_object.method1().method2().method3(arg1, arg2))
michael@0 495 self.mox.VerifyAll()
michael@0 496
michael@0 497 # Mocker
michael@0 498 # (TODO)
michael@0 499
michael@0 500 ::
michael@0 501
michael@0 502 >>> # Dingus
michael@0 503 >>> my_dingus = dingus.Dingus()
michael@0 504 >>> method3 = my_dingus.method1.return_value.method2.return_value.method3
michael@0 505 >>> method3.return_value = 'some value'
michael@0 506 >>> assertEqual('some value', my_dingus.method1().method2().method3(1, 2))
michael@0 507 >>> assert method3.calls('()', 1, 2).once()
michael@0 508
michael@0 509 ::
michael@0 510
michael@0 511 >>> # fudge
michael@0 512 >>> @fudge.test
michael@0 513 ... def test():
michael@0 514 ... my_fake = fudge.Fake()
michael@0 515 ... (my_fake
michael@0 516 ... .expects('method1')
michael@0 517 ... .returns_fake()
michael@0 518 ... .expects('method2')
michael@0 519 ... .returns_fake()
michael@0 520 ... .expects('method3')
michael@0 521 ... .with_args(1, 2)
michael@0 522 ... .returns('some value'))
michael@0 523 ... assertEqual('some value', my_fake.method1().method2().method3(1, 2))
michael@0 524 ...
michael@0 525 >>> test()
michael@0 526
michael@0 527
michael@0 528 Mocking a context manager
michael@0 529 ~~~~~~~~~~~~~~~~~~~~~~~~~
michael@0 530
michael@0 531 Examples for mock, Dingus and fudge only (so far):
michael@0 532
michael@0 533 .. doctest::
michael@0 534
michael@0 535 >>> # mock
michael@0 536 >>> my_mock = mock.MagicMock()
michael@0 537 >>> with my_mock:
michael@0 538 ... pass
michael@0 539 ...
michael@0 540 >>> my_mock.__enter__.assert_called_with()
michael@0 541 >>> my_mock.__exit__.assert_called_with(None, None, None)
michael@0 542
michael@0 543 ::
michael@0 544
michael@0 545
michael@0 546 >>> # Dingus (nothing special here; all dinguses are "magic mocks")
michael@0 547 >>> my_dingus = dingus.Dingus()
michael@0 548 >>> with my_dingus:
michael@0 549 ... pass
michael@0 550 ...
michael@0 551 >>> assert my_dingus.__enter__.calls()
michael@0 552 >>> assert my_dingus.__exit__.calls('()', None, None, None)
michael@0 553
michael@0 554 ::
michael@0 555
michael@0 556 >>> # fudge
michael@0 557 >>> my_fake = fudge.Fake().provides('__enter__').provides('__exit__')
michael@0 558 >>> with my_fake:
michael@0 559 ... pass
michael@0 560 ...
michael@0 561
michael@0 562
michael@0 563 Mocking the builtin open used as a context manager
michael@0 564 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
michael@0 565
michael@0 566 Example for mock only (so far):
michael@0 567
michael@0 568 .. doctest::
michael@0 569
michael@0 570 >>> # mock
michael@0 571 >>> my_mock = mock.MagicMock()
michael@0 572 >>> with mock.patch('__builtin__.open', my_mock):
michael@0 573 ... manager = my_mock.return_value.__enter__.return_value
michael@0 574 ... manager.read.return_value = 'some data'
michael@0 575 ... with open('foo') as h:
michael@0 576 ... data = h.read()
michael@0 577 ...
michael@0 578 >>> data
michael@0 579 'some data'
michael@0 580 >>> my_mock.assert_called_once_with('foo')
michael@0 581
michael@0 582 *or*:
michael@0 583
michael@0 584 .. doctest::
michael@0 585
michael@0 586 >>> # mock
michael@0 587 >>> with mock.patch('__builtin__.open') as my_mock:
michael@0 588 ... my_mock.return_value.__enter__ = lambda s: s
michael@0 589 ... my_mock.return_value.__exit__ = mock.Mock()
michael@0 590 ... my_mock.return_value.read.return_value = 'some data'
michael@0 591 ... with open('foo') as h:
michael@0 592 ... data = h.read()
michael@0 593 ...
michael@0 594 >>> data
michael@0 595 'some data'
michael@0 596 >>> my_mock.assert_called_once_with('foo')
michael@0 597
michael@0 598 ::
michael@0 599
michael@0 600 >>> # Dingus
michael@0 601 >>> my_dingus = dingus.Dingus()
michael@0 602 >>> with dingus.patch('__builtin__.open', my_dingus):
michael@0 603 ... file_ = open.return_value.__enter__.return_value
michael@0 604 ... file_.read.return_value = 'some data'
michael@0 605 ... with open('foo') as h:
michael@0 606 ... data = f.read()
michael@0 607 ...
michael@0 608 >>> data
michael@0 609 'some data'
michael@0 610 >>> assert my_dingus.calls('()', 'foo').once()
michael@0 611
michael@0 612 ::
michael@0 613
michael@0 614 >>> # fudge
michael@0 615 >>> from contextlib import contextmanager
michael@0 616 >>> from StringIO import StringIO
michael@0 617 >>> @contextmanager
michael@0 618 ... def fake_file(filename):
michael@0 619 ... yield StringIO('sekrets')
michael@0 620 ...
michael@0 621 >>> with fudge.patch('__builtin__.open') as fake_open:
michael@0 622 ... fake_open.is_callable().calls(fake_file)
michael@0 623 ... with open('/etc/password') as f:
michael@0 624 ... data = f.read()
michael@0 625 ...
michael@0 626 fake:__builtin__.open
michael@0 627 >>> data
michael@0 628 'sekrets'

mercurial