test_pytest_mock.py 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825
  1. import os
  2. import platform
  3. import sys
  4. from contextlib import contextmanager
  5. import py.code
  6. import pytest
  7. pytest_plugins = "pytester"
  8. # could not make some of the tests work on PyPy, patches are welcome!
  9. skip_pypy = pytest.mark.skipif(
  10. platform.python_implementation() == "PyPy", reason="could not make it work on pypy"
  11. )
  12. # Python 3.8 changed the output formatting (bpo-35500), which has been ported to mock 3.0
  13. NEW_FORMATTING = sys.version_info >= (3, 8) or sys.version_info[0] == 2
  14. @pytest.fixture
  15. def needs_assert_rewrite(pytestconfig):
  16. """
  17. Fixture which skips requesting test if assertion rewrite is disabled (#102)
  18. Making this a fixture to avoid acessing pytest's config in the global context.
  19. """
  20. option = pytestconfig.getoption("assertmode")
  21. if option != "rewrite":
  22. pytest.skip(
  23. "this test needs assertion rewrite to work but current option "
  24. 'is "{}"'.format(option)
  25. )
  26. class UnixFS(object):
  27. """
  28. Wrapper to os functions to simulate a Unix file system, used for testing
  29. the mock fixture.
  30. """
  31. @classmethod
  32. def rm(cls, filename):
  33. os.remove(filename)
  34. @classmethod
  35. def ls(cls, path):
  36. return os.listdir(path)
  37. @pytest.fixture
  38. def check_unix_fs_mocked(tmpdir, mocker):
  39. """
  40. performs a standard test in a UnixFS, assuming that both `os.remove` and
  41. `os.listdir` have been mocked previously.
  42. """
  43. def check(mocked_rm, mocked_ls):
  44. assert mocked_rm is os.remove
  45. assert mocked_ls is os.listdir
  46. file_name = tmpdir / "foo.txt"
  47. file_name.ensure()
  48. UnixFS.rm(str(file_name))
  49. mocked_rm.assert_called_once_with(str(file_name))
  50. assert os.path.isfile(str(file_name))
  51. mocked_ls.return_value = ["bar.txt"]
  52. assert UnixFS.ls(str(tmpdir)) == ["bar.txt"]
  53. mocked_ls.assert_called_once_with(str(tmpdir))
  54. mocker.stopall()
  55. assert UnixFS.ls(str(tmpdir)) == ["foo.txt"]
  56. UnixFS.rm(str(file_name))
  57. assert not os.path.isfile(str(file_name))
  58. return check
  59. def mock_using_patch_object(mocker):
  60. return mocker.patch.object(os, "remove"), mocker.patch.object(os, "listdir")
  61. def mock_using_patch(mocker):
  62. return mocker.patch("os.remove"), mocker.patch("os.listdir")
  63. def mock_using_patch_multiple(mocker):
  64. r = mocker.patch.multiple("os", remove=mocker.DEFAULT, listdir=mocker.DEFAULT)
  65. return r["remove"], r["listdir"]
  66. @pytest.mark.parametrize(
  67. "mock_fs", [mock_using_patch_object, mock_using_patch, mock_using_patch_multiple]
  68. )
  69. def test_mock_patches(mock_fs, mocker, check_unix_fs_mocked):
  70. """
  71. Installs mocks into `os` functions and performs a standard testing of
  72. mock functionality. We parametrize different mock methods to ensure
  73. all (intended, at least) mock API is covered.
  74. """
  75. # mock it twice on purpose to ensure we unmock it correctly later
  76. mock_fs(mocker)
  77. mocked_rm, mocked_ls = mock_fs(mocker)
  78. check_unix_fs_mocked(mocked_rm, mocked_ls)
  79. mocker.resetall()
  80. mocker.stopall()
  81. def test_mock_patch_dict(mocker):
  82. """
  83. Testing
  84. :param mock:
  85. """
  86. x = {"original": 1}
  87. mocker.patch.dict(x, values=[("new", 10)], clear=True)
  88. assert x == {"new": 10}
  89. mocker.stopall()
  90. assert x == {"original": 1}
  91. def test_mock_patch_dict_resetall(mocker):
  92. """
  93. We can call resetall after patching a dict.
  94. :param mock:
  95. """
  96. x = {"original": 1}
  97. mocker.patch.dict(x, values=[("new", 10)], clear=True)
  98. assert x == {"new": 10}
  99. mocker.resetall()
  100. assert x == {"new": 10}
  101. @pytest.mark.parametrize(
  102. "name",
  103. [
  104. "ANY",
  105. "call",
  106. "create_autospec",
  107. "MagicMock",
  108. "Mock",
  109. "mock_open",
  110. "NonCallableMock",
  111. "PropertyMock",
  112. "sentinel",
  113. ],
  114. )
  115. def test_mocker_aliases(name, pytestconfig):
  116. from pytest_mock import _get_mock_module, MockFixture
  117. mock_module = _get_mock_module(pytestconfig)
  118. mocker = MockFixture(pytestconfig)
  119. assert getattr(mocker, name) is getattr(mock_module, name)
  120. def test_mocker_resetall(mocker):
  121. listdir = mocker.patch("os.listdir")
  122. open = mocker.patch("os.open")
  123. listdir("/tmp")
  124. open("/tmp/foo.txt")
  125. listdir.assert_called_once_with("/tmp")
  126. open.assert_called_once_with("/tmp/foo.txt")
  127. mocker.resetall()
  128. assert not listdir.called
  129. assert not open.called
  130. class TestMockerStub:
  131. def test_call(self, mocker):
  132. stub = mocker.stub()
  133. stub("foo", "bar")
  134. stub.assert_called_once_with("foo", "bar")
  135. def test_repr_with_no_name(self, mocker):
  136. stub = mocker.stub()
  137. assert "name" not in repr(stub)
  138. def test_repr_with_name(self, mocker):
  139. test_name = "funny walk"
  140. stub = mocker.stub(name=test_name)
  141. assert "name={0!r}".format(test_name) in repr(stub)
  142. def __test_failure_message(self, mocker, **kwargs):
  143. expected_name = kwargs.get("name") or "mock"
  144. if NEW_FORMATTING:
  145. msg = "expected call not found.\nExpected: {0}()\nActual: not called."
  146. else:
  147. msg = "Expected call: {0}()\nNot called"
  148. expected_message = msg.format(expected_name)
  149. stub = mocker.stub(**kwargs)
  150. with pytest.raises(AssertionError) as exc_info:
  151. stub.assert_called_with()
  152. assert str(exc_info.value) == expected_message
  153. def test_failure_message_with_no_name(self, mocker):
  154. self.__test_failure_message(mocker)
  155. @pytest.mark.parametrize("name", (None, "", "f", "The Castle of aaarrrrggh"))
  156. def test_failure_message_with_name(self, mocker, name):
  157. self.__test_failure_message(mocker, name=name)
  158. def test_instance_method_spy(mocker):
  159. class Foo(object):
  160. def bar(self, arg):
  161. return arg * 2
  162. foo = Foo()
  163. other = Foo()
  164. spy = mocker.spy(foo, "bar")
  165. assert foo.bar(arg=10) == 20
  166. assert other.bar(arg=10) == 20
  167. foo.bar.assert_called_once_with(arg=10)
  168. assert foo.bar.spy_return == 20
  169. spy.assert_called_once_with(arg=10)
  170. assert spy.spy_return == 20
  171. def test_instance_method_spy_exception(mocker):
  172. class Foo(object):
  173. def bar(self, arg):
  174. raise Exception("Error with {}".format(arg))
  175. foo = Foo()
  176. spy = mocker.spy(foo, "bar")
  177. expected_calls = []
  178. for i, v in enumerate([10, 20]):
  179. with pytest.raises(Exception, match="Error with {}".format(v)) as exc_info:
  180. foo.bar(arg=v)
  181. expected_calls.append(mocker.call(arg=v))
  182. assert foo.bar.call_args_list == expected_calls
  183. assert str(spy.spy_exception) == "Error with {}".format(v)
  184. def test_spy_reset(mocker):
  185. class Foo(object):
  186. def bar(self, x):
  187. if x == 0:
  188. raise ValueError("invalid x")
  189. return x * 3
  190. spy = mocker.spy(Foo, "bar")
  191. assert spy.spy_return is None
  192. assert spy.spy_exception is None
  193. Foo().bar(10)
  194. assert spy.spy_return == 30
  195. assert spy.spy_exception is None
  196. with pytest.raises(ValueError):
  197. Foo().bar(0)
  198. assert spy.spy_return is None
  199. assert str(spy.spy_exception) == "invalid x"
  200. Foo().bar(15)
  201. assert spy.spy_return == 45
  202. assert spy.spy_exception is None
  203. @skip_pypy
  204. def test_instance_method_by_class_spy(mocker):
  205. class Foo(object):
  206. def bar(self, arg):
  207. return arg * 2
  208. spy = mocker.spy(Foo, "bar")
  209. foo = Foo()
  210. other = Foo()
  211. assert foo.bar(arg=10) == 20
  212. assert other.bar(arg=10) == 20
  213. calls = [mocker.call(foo, arg=10), mocker.call(other, arg=10)]
  214. assert spy.call_args_list == calls
  215. @skip_pypy
  216. def test_instance_method_by_subclass_spy(mocker):
  217. class Base(object):
  218. def bar(self, arg):
  219. return arg * 2
  220. class Foo(Base):
  221. pass
  222. spy = mocker.spy(Foo, "bar")
  223. foo = Foo()
  224. other = Foo()
  225. assert foo.bar(arg=10) == 20
  226. assert other.bar(arg=10) == 20
  227. calls = [mocker.call(foo, arg=10), mocker.call(other, arg=10)]
  228. assert spy.call_args_list == calls
  229. assert spy.spy_return == 20
  230. @skip_pypy
  231. def test_class_method_spy(mocker):
  232. class Foo(object):
  233. @classmethod
  234. def bar(cls, arg):
  235. return arg * 2
  236. spy = mocker.spy(Foo, "bar")
  237. assert Foo.bar(arg=10) == 20
  238. Foo.bar.assert_called_once_with(arg=10)
  239. assert Foo.bar.spy_return == 20
  240. spy.assert_called_once_with(arg=10)
  241. assert spy.spy_return == 20
  242. @skip_pypy
  243. @pytest.mark.xfail(sys.version_info[0] == 2, reason="does not work on Python 2")
  244. def test_class_method_subclass_spy(mocker):
  245. class Base(object):
  246. @classmethod
  247. def bar(self, arg):
  248. return arg * 2
  249. class Foo(Base):
  250. pass
  251. spy = mocker.spy(Foo, "bar")
  252. assert Foo.bar(arg=10) == 20
  253. Foo.bar.assert_called_once_with(arg=10)
  254. assert Foo.bar.spy_return == 20
  255. spy.assert_called_once_with(arg=10)
  256. assert spy.spy_return == 20
  257. @skip_pypy
  258. def test_class_method_with_metaclass_spy(mocker):
  259. class MetaFoo(type):
  260. pass
  261. class Foo(object):
  262. __metaclass__ = MetaFoo
  263. @classmethod
  264. def bar(cls, arg):
  265. return arg * 2
  266. spy = mocker.spy(Foo, "bar")
  267. assert Foo.bar(arg=10) == 20
  268. Foo.bar.assert_called_once_with(arg=10)
  269. assert Foo.bar.spy_return == 20
  270. spy.assert_called_once_with(arg=10)
  271. assert spy.spy_return == 20
  272. @skip_pypy
  273. def test_static_method_spy(mocker):
  274. class Foo(object):
  275. @staticmethod
  276. def bar(arg):
  277. return arg * 2
  278. spy = mocker.spy(Foo, "bar")
  279. assert Foo.bar(arg=10) == 20
  280. Foo.bar.assert_called_once_with(arg=10)
  281. assert Foo.bar.spy_return == 20
  282. spy.assert_called_once_with(arg=10)
  283. assert spy.spy_return == 20
  284. @skip_pypy
  285. @pytest.mark.xfail(sys.version_info[0] == 2, reason="does not work on Python 2")
  286. def test_static_method_subclass_spy(mocker):
  287. class Base(object):
  288. @staticmethod
  289. def bar(arg):
  290. return arg * 2
  291. class Foo(Base):
  292. pass
  293. spy = mocker.spy(Foo, "bar")
  294. assert Foo.bar(arg=10) == 20
  295. Foo.bar.assert_called_once_with(arg=10)
  296. assert Foo.bar.spy_return == 20
  297. spy.assert_called_once_with(arg=10)
  298. assert spy.spy_return == 20
  299. @pytest.mark.skip("Skip testdir")
  300. def test_callable_like_spy(testdir, mocker):
  301. testdir.makepyfile(
  302. uut="""
  303. class CallLike(object):
  304. def __call__(self, x):
  305. return x * 2
  306. call_like = CallLike()
  307. """
  308. )
  309. testdir.syspathinsert()
  310. import uut
  311. spy = mocker.spy(uut, "call_like")
  312. uut.call_like(10)
  313. spy.assert_called_once_with(10)
  314. assert spy.spy_return == 20
  315. @contextmanager
  316. def assert_traceback():
  317. """
  318. Assert that this file is at the top of the filtered traceback
  319. """
  320. try:
  321. yield
  322. except AssertionError:
  323. traceback = py.code.ExceptionInfo().traceback
  324. crashentry = traceback.getcrashentry()
  325. assert crashentry.path == __file__
  326. else:
  327. raise AssertionError("DID NOT RAISE")
  328. @contextmanager
  329. def assert_argument_introspection(left, right):
  330. """
  331. Assert detailed argument introspection is used
  332. """
  333. try:
  334. yield
  335. except AssertionError as e:
  336. # this may be a bit too assuming, but seems nicer then hard-coding
  337. import _pytest.assertion.util as util
  338. # NOTE: we assert with either verbose or not, depending on how our own
  339. # test was run by examining sys.argv
  340. verbose = any(a.startswith("-v") for a in sys.argv)
  341. expected = "\n ".join(util._compare_eq_iterable(left, right, verbose))
  342. assert expected in str(e)
  343. else:
  344. raise AssertionError("DID NOT RAISE")
  345. @pytest.mark.skipif(
  346. sys.version_info[:2] == (3, 4),
  347. reason="assert_not_called not available in Python 3.4",
  348. )
  349. def test_assert_not_called_wrapper(mocker):
  350. stub = mocker.stub()
  351. stub.assert_not_called()
  352. stub()
  353. with assert_traceback():
  354. stub.assert_not_called()
  355. def test_assert_called_with_wrapper(mocker):
  356. stub = mocker.stub()
  357. stub("foo")
  358. stub.assert_called_with("foo")
  359. with assert_traceback():
  360. stub.assert_called_with("bar")
  361. def test_assert_called_once_with_wrapper(mocker):
  362. stub = mocker.stub()
  363. stub("foo")
  364. stub.assert_called_once_with("foo")
  365. stub("foo")
  366. with assert_traceback():
  367. stub.assert_called_once_with("foo")
  368. def test_assert_called_once_wrapper(mocker):
  369. stub = mocker.stub()
  370. if not hasattr(stub, "assert_called_once"):
  371. pytest.skip("assert_called_once not available")
  372. stub("foo")
  373. stub.assert_called_once()
  374. stub("foo")
  375. with assert_traceback():
  376. stub.assert_called_once()
  377. def test_assert_called_wrapper(mocker):
  378. stub = mocker.stub()
  379. if not hasattr(stub, "assert_called"):
  380. pytest.skip("assert_called_once not available")
  381. with assert_traceback():
  382. stub.assert_called()
  383. stub("foo")
  384. stub.assert_called()
  385. stub("foo")
  386. stub.assert_called()
  387. @pytest.mark.skip
  388. @pytest.mark.usefixtures("needs_assert_rewrite")
  389. def test_assert_called_args_with_introspection(mocker):
  390. stub = mocker.stub()
  391. complex_args = ("a", 1, set(["test"]))
  392. wrong_args = ("b", 2, set(["jest"]))
  393. stub(*complex_args)
  394. stub.assert_called_with(*complex_args)
  395. stub.assert_called_once_with(*complex_args)
  396. with assert_argument_introspection(complex_args, wrong_args):
  397. stub.assert_called_with(*wrong_args)
  398. stub.assert_called_once_with(*wrong_args)
  399. @pytest.mark.skip
  400. @pytest.mark.usefixtures("needs_assert_rewrite")
  401. def test_assert_called_kwargs_with_introspection(mocker):
  402. stub = mocker.stub()
  403. complex_kwargs = dict(foo={"bar": 1, "baz": "spam"})
  404. wrong_kwargs = dict(foo={"goo": 1, "baz": "bran"})
  405. stub(**complex_kwargs)
  406. stub.assert_called_with(**complex_kwargs)
  407. stub.assert_called_once_with(**complex_kwargs)
  408. with assert_argument_introspection(complex_kwargs, wrong_kwargs):
  409. stub.assert_called_with(**wrong_kwargs)
  410. stub.assert_called_once_with(**wrong_kwargs)
  411. def test_assert_any_call_wrapper(mocker):
  412. stub = mocker.stub()
  413. stub("foo")
  414. stub("foo")
  415. stub.assert_any_call("foo")
  416. with assert_traceback():
  417. stub.assert_any_call("bar")
  418. def test_assert_has_calls(mocker):
  419. stub = mocker.stub()
  420. stub("foo")
  421. stub.assert_has_calls([mocker.call("foo")])
  422. with assert_traceback():
  423. stub.assert_has_calls([mocker.call("bar")])
  424. @pytest.mark.skip("Skip testdir")
  425. def test_monkeypatch_ini(mocker, testdir):
  426. # Make sure the following function actually tests something
  427. stub = mocker.stub()
  428. assert stub.assert_called_with.__module__ != stub.__module__
  429. testdir.makepyfile(
  430. """
  431. import py.code
  432. def test_foo(mocker):
  433. stub = mocker.stub()
  434. assert stub.assert_called_with.__module__ == stub.__module__
  435. """
  436. )
  437. testdir.makeini(
  438. """
  439. [pytest]
  440. mock_traceback_monkeypatch = false
  441. """
  442. )
  443. result = runpytest_subprocess(testdir)
  444. assert result.ret == 0
  445. def test_parse_ini_boolean():
  446. import pytest_mock
  447. assert pytest_mock.parse_ini_boolean("True") is True
  448. assert pytest_mock.parse_ini_boolean("false") is False
  449. with pytest.raises(ValueError):
  450. pytest_mock.parse_ini_boolean("foo")
  451. def test_patched_method_parameter_name(mocker):
  452. """Test that our internal code uses uncommon names when wrapping other
  453. "mock" methods to avoid conflicts with user code (#31).
  454. """
  455. class Request:
  456. @classmethod
  457. def request(cls, method, args):
  458. pass
  459. m = mocker.patch.object(Request, "request")
  460. Request.request(method="get", args={"type": "application/json"})
  461. m.assert_called_once_with(method="get", args={"type": "application/json"})
  462. @pytest.mark.skip("Skip testdir")
  463. def test_monkeypatch_native(testdir):
  464. """Automatically disable monkeypatching when --tb=native.
  465. """
  466. testdir.makepyfile(
  467. """
  468. def test_foo(mocker):
  469. stub = mocker.stub()
  470. stub(1, greet='hello')
  471. stub.assert_called_once_with(1, greet='hey')
  472. """
  473. )
  474. result = runpytest_subprocess(testdir, "--tb=native")
  475. assert result.ret == 1
  476. assert "During handling of the above exception" not in result.stdout.str()
  477. assert "Differing items:" not in result.stdout.str()
  478. traceback_lines = [
  479. x
  480. for x in result.stdout.str().splitlines()
  481. if "Traceback (most recent call last)" in x
  482. ]
  483. assert (
  484. len(traceback_lines) == 1
  485. ) # make sure there are no duplicated tracebacks (#44)
  486. @pytest.mark.skip("Skip testdir")
  487. def test_monkeypatch_no_terminal(testdir):
  488. """Don't crash without 'terminal' plugin.
  489. """
  490. testdir.makepyfile(
  491. """
  492. def test_foo(mocker):
  493. stub = mocker.stub()
  494. stub(1, greet='hello')
  495. stub.assert_called_once_with(1, greet='hey')
  496. """
  497. )
  498. result = runpytest_subprocess(testdir, "-p", "no:terminal", "-s")
  499. assert result.ret == 1
  500. assert result.stdout.lines == []
  501. @pytest.mark.skip("Skip testdir")
  502. @pytest.mark.skipif(sys.version_info[0] < 3, reason="Py3 only")
  503. def test_standalone_mock(testdir):
  504. """Check that the "mock_use_standalone" is being used.
  505. """
  506. testdir.makepyfile(
  507. """
  508. def test_foo(mocker):
  509. pass
  510. """
  511. )
  512. testdir.makeini(
  513. """
  514. [pytest]
  515. mock_use_standalone_module = true
  516. """
  517. )
  518. result = runpytest_subprocess(testdir)
  519. assert result.ret == 3
  520. result.stderr.fnmatch_lines(["*No module named 'mock'*"])
  521. def runpytest_subprocess(testdir, *args):
  522. """Testdir.runpytest_subprocess only available in pytest-2.8+"""
  523. if hasattr(testdir, "runpytest_subprocess"):
  524. return testdir.runpytest_subprocess(*args)
  525. else:
  526. # pytest 2.7.X
  527. return testdir.runpytest(*args)
  528. @pytest.mark.skip("Skip testdir")
  529. @pytest.mark.usefixtures("needs_assert_rewrite")
  530. def test_detailed_introspection(testdir):
  531. """Check that the "mock_use_standalone" is being used.
  532. """
  533. testdir.makepyfile(
  534. """
  535. def test(mocker):
  536. m = mocker.Mock()
  537. m('fo')
  538. m.assert_called_once_with('', bar=4)
  539. """
  540. )
  541. result = testdir.runpytest("-s")
  542. if NEW_FORMATTING:
  543. expected_lines = [
  544. "*AssertionError: expected call not found.",
  545. "*Expected: mock('', bar=4)",
  546. "*Actual: mock('fo')",
  547. ]
  548. else:
  549. expected_lines = [
  550. "*AssertionError: Expected call: mock('', bar=4)*",
  551. "*Actual call: mock('fo')*",
  552. ]
  553. expected_lines += [
  554. "*pytest introspection follows:*",
  555. "*Args:",
  556. "*assert ('fo',) == ('',)",
  557. "*At index 0 diff: 'fo' != ''*",
  558. "*Use -v to get the full diff*",
  559. "*Kwargs:*",
  560. "*assert {} == {'bar': 4}*",
  561. "*Right contains* more item*",
  562. "*{'bar': 4}*",
  563. "*Use -v to get the full diff*",
  564. ]
  565. result.stdout.fnmatch_lines(expected_lines)
  566. @pytest.mark.skip("Skip testdir")
  567. def test_missing_introspection(testdir):
  568. testdir.makepyfile(
  569. """
  570. def test_foo(mocker):
  571. mock = mocker.Mock()
  572. mock('foo')
  573. mock('test')
  574. mock.assert_called_once_with('test')
  575. """
  576. )
  577. result = testdir.runpytest()
  578. assert "pytest introspection follows:" not in result.stdout.str()
  579. def test_assert_called_with_unicode_arguments(mocker):
  580. """Test bug in assert_call_with called with non-ascii unicode string (#91)"""
  581. stub = mocker.stub()
  582. stub(b"l\xc3\xb6k".decode("UTF-8"))
  583. with pytest.raises(AssertionError):
  584. stub.assert_called_with(u"lak")
  585. @pytest.mark.skip("Skip testdir")
  586. def test_plain_stopall(testdir):
  587. """patch.stopall() in a test should not cause an error during unconfigure (#137)"""
  588. testdir.makepyfile(
  589. """
  590. import random
  591. def get_random_number():
  592. return random.randint(0, 100)
  593. def test_get_random_number(mocker):
  594. patcher = mocker.mock_module.patch("random.randint", lambda x, y: 5)
  595. patcher.start()
  596. assert get_random_number() == 5
  597. mocker.mock_module.patch.stopall()
  598. """
  599. )
  600. result = testdir.runpytest_subprocess()
  601. result.stdout.fnmatch_lines("* 1 passed in *")
  602. assert "RuntimeError" not in result.stderr.str()
  603. def test_abort_patch_object_context_manager(mocker):
  604. class A(object):
  605. def doIt(self):
  606. return False
  607. a = A()
  608. with pytest.raises(ValueError) as excinfo:
  609. with mocker.patch.object(a, "doIt", return_value=True):
  610. assert a.doIt() == True
  611. expected_error_msg = (
  612. "Using mocker in a with context is not supported. "
  613. "https://github.com/pytest-dev/pytest-mock#note-about-usage-as-context-manager"
  614. )
  615. assert str(excinfo.value) == expected_error_msg
  616. def test_abort_patch_context_manager(mocker):
  617. with pytest.raises(ValueError) as excinfo:
  618. with mocker.patch("some_package"):
  619. pass
  620. expected_error_msg = (
  621. "Using mocker in a with context is not supported. "
  622. "https://github.com/pytest-dev/pytest-mock#note-about-usage-as-context-manager"
  623. )
  624. assert str(excinfo.value) == expected_error_msg
  625. @pytest.mark.skip("Skip testdir")
  626. def test_abort_patch_context_manager_with_stale_pyc(testdir):
  627. """Ensure we don't trigger an error in case the frame where mocker.patch is being
  628. used doesn't have a 'context' (#169)"""
  629. import compileall
  630. py_fn = testdir.makepyfile(
  631. c="""
  632. class C:
  633. x = 1
  634. def check(mocker):
  635. mocker.patch.object(C, "x", 2)
  636. assert C.x == 2
  637. """
  638. )
  639. testdir.syspathinsert()
  640. testdir.makepyfile(
  641. """
  642. from c import check
  643. def test_foo(mocker):
  644. check(mocker)
  645. """
  646. )
  647. result = testdir.runpytest()
  648. result.stdout.fnmatch_lines("* 1 passed *")
  649. kwargs = {"legacy": True} if sys.version_info[0] >= 3 else {}
  650. assert compileall.compile_file(str(py_fn), **kwargs)
  651. pyc_fn = str(py_fn) + "c"
  652. assert os.path.isfile(pyc_fn)
  653. py_fn.remove()
  654. result = testdir.runpytest()
  655. result.stdout.fnmatch_lines("* 1 passed *")