| from __future__ import absolute_import, division, print_function |
| import os |
| import sys |
| import textwrap |
| |
| import pytest |
| from _pytest.monkeypatch import MonkeyPatch |
| |
| |
| @pytest.fixture |
| def mp(): |
| cwd = os.getcwd() |
| sys_path = list(sys.path) |
| yield MonkeyPatch() |
| sys.path[:] = sys_path |
| os.chdir(cwd) |
| |
| |
| def test_setattr(): |
| class A(object): |
| x = 1 |
| |
| monkeypatch = MonkeyPatch() |
| pytest.raises(AttributeError, "monkeypatch.setattr(A, 'notexists', 2)") |
| monkeypatch.setattr(A, "y", 2, raising=False) |
| assert A.y == 2 |
| monkeypatch.undo() |
| assert not hasattr(A, "y") |
| |
| monkeypatch = MonkeyPatch() |
| monkeypatch.setattr(A, "x", 2) |
| assert A.x == 2 |
| monkeypatch.setattr(A, "x", 3) |
| assert A.x == 3 |
| monkeypatch.undo() |
| assert A.x == 1 |
| |
| A.x = 5 |
| monkeypatch.undo() # double-undo makes no modification |
| assert A.x == 5 |
| |
| |
| class TestSetattrWithImportPath(object): |
| def test_string_expression(self, monkeypatch): |
| monkeypatch.setattr("os.path.abspath", lambda x: "hello2") |
| assert os.path.abspath("123") == "hello2" |
| |
| def test_string_expression_class(self, monkeypatch): |
| monkeypatch.setattr("_pytest.config.Config", 42) |
| import _pytest |
| |
| assert _pytest.config.Config == 42 |
| |
| def test_unicode_string(self, monkeypatch): |
| monkeypatch.setattr("_pytest.config.Config", 42) |
| import _pytest |
| |
| assert _pytest.config.Config == 42 |
| monkeypatch.delattr("_pytest.config.Config") |
| |
| def test_wrong_target(self, monkeypatch): |
| pytest.raises(TypeError, lambda: monkeypatch.setattr(None, None)) |
| |
| def test_unknown_import(self, monkeypatch): |
| pytest.raises(ImportError, lambda: monkeypatch.setattr("unkn123.classx", None)) |
| |
| def test_unknown_attr(self, monkeypatch): |
| pytest.raises( |
| AttributeError, lambda: monkeypatch.setattr("os.path.qweqwe", None) |
| ) |
| |
| def test_unknown_attr_non_raising(self, monkeypatch): |
| # https://github.com/pytest-dev/pytest/issues/746 |
| monkeypatch.setattr("os.path.qweqwe", 42, raising=False) |
| assert os.path.qweqwe == 42 |
| |
| def test_delattr(self, monkeypatch): |
| monkeypatch.delattr("os.path.abspath") |
| assert not hasattr(os.path, "abspath") |
| monkeypatch.undo() |
| assert os.path.abspath |
| |
| |
| def test_delattr(): |
| class A(object): |
| x = 1 |
| |
| monkeypatch = MonkeyPatch() |
| monkeypatch.delattr(A, "x") |
| assert not hasattr(A, "x") |
| monkeypatch.undo() |
| assert A.x == 1 |
| |
| monkeypatch = MonkeyPatch() |
| monkeypatch.delattr(A, "x") |
| pytest.raises(AttributeError, "monkeypatch.delattr(A, 'y')") |
| monkeypatch.delattr(A, "y", raising=False) |
| monkeypatch.setattr(A, "x", 5, raising=False) |
| assert A.x == 5 |
| monkeypatch.undo() |
| assert A.x == 1 |
| |
| |
| def test_setitem(): |
| d = {"x": 1} |
| monkeypatch = MonkeyPatch() |
| monkeypatch.setitem(d, "x", 2) |
| monkeypatch.setitem(d, "y", 1700) |
| monkeypatch.setitem(d, "y", 1700) |
| assert d["x"] == 2 |
| assert d["y"] == 1700 |
| monkeypatch.setitem(d, "x", 3) |
| assert d["x"] == 3 |
| monkeypatch.undo() |
| assert d["x"] == 1 |
| assert "y" not in d |
| d["x"] = 5 |
| monkeypatch.undo() |
| assert d["x"] == 5 |
| |
| |
| def test_setitem_deleted_meanwhile(): |
| d = {} |
| monkeypatch = MonkeyPatch() |
| monkeypatch.setitem(d, "x", 2) |
| del d["x"] |
| monkeypatch.undo() |
| assert not d |
| |
| |
| @pytest.mark.parametrize("before", [True, False]) |
| def test_setenv_deleted_meanwhile(before): |
| key = "qwpeoip123" |
| if before: |
| os.environ[key] = "world" |
| monkeypatch = MonkeyPatch() |
| monkeypatch.setenv(key, "hello") |
| del os.environ[key] |
| monkeypatch.undo() |
| if before: |
| assert os.environ[key] == "world" |
| del os.environ[key] |
| else: |
| assert key not in os.environ |
| |
| |
| def test_delitem(): |
| d = {"x": 1} |
| monkeypatch = MonkeyPatch() |
| monkeypatch.delitem(d, "x") |
| assert "x" not in d |
| monkeypatch.delitem(d, "y", raising=False) |
| pytest.raises(KeyError, "monkeypatch.delitem(d, 'y')") |
| assert not d |
| monkeypatch.setitem(d, "y", 1700) |
| assert d["y"] == 1700 |
| d["hello"] = "world" |
| monkeypatch.setitem(d, "x", 1500) |
| assert d["x"] == 1500 |
| monkeypatch.undo() |
| assert d == {"hello": "world", "x": 1} |
| |
| |
| def test_setenv(): |
| monkeypatch = MonkeyPatch() |
| monkeypatch.setenv("XYZ123", 2) |
| import os |
| |
| assert os.environ["XYZ123"] == "2" |
| monkeypatch.undo() |
| assert "XYZ123" not in os.environ |
| |
| |
| def test_delenv(): |
| name = "xyz1234" |
| assert name not in os.environ |
| monkeypatch = MonkeyPatch() |
| pytest.raises(KeyError, "monkeypatch.delenv(%r, raising=True)" % name) |
| monkeypatch.delenv(name, raising=False) |
| monkeypatch.undo() |
| os.environ[name] = "1" |
| try: |
| monkeypatch = MonkeyPatch() |
| monkeypatch.delenv(name) |
| assert name not in os.environ |
| monkeypatch.setenv(name, "3") |
| assert os.environ[name] == "3" |
| monkeypatch.undo() |
| assert os.environ[name] == "1" |
| finally: |
| if name in os.environ: |
| del os.environ[name] |
| |
| |
| def test_setenv_prepend(): |
| import os |
| |
| monkeypatch = MonkeyPatch() |
| monkeypatch.setenv("XYZ123", 2, prepend="-") |
| assert os.environ["XYZ123"] == "2" |
| monkeypatch.setenv("XYZ123", 3, prepend="-") |
| assert os.environ["XYZ123"] == "3-2" |
| monkeypatch.undo() |
| assert "XYZ123" not in os.environ |
| |
| |
| def test_monkeypatch_plugin(testdir): |
| reprec = testdir.inline_runsource( |
| """ |
| def test_method(monkeypatch): |
| assert monkeypatch.__class__.__name__ == "MonkeyPatch" |
| """ |
| ) |
| res = reprec.countoutcomes() |
| assert tuple(res) == (1, 0, 0), res |
| |
| |
| def test_syspath_prepend(mp): |
| old = list(sys.path) |
| mp.syspath_prepend("world") |
| mp.syspath_prepend("hello") |
| assert sys.path[0] == "hello" |
| assert sys.path[1] == "world" |
| mp.undo() |
| assert sys.path == old |
| mp.undo() |
| assert sys.path == old |
| |
| |
| def test_syspath_prepend_double_undo(mp): |
| mp.syspath_prepend("hello world") |
| mp.undo() |
| sys.path.append("more hello world") |
| mp.undo() |
| assert sys.path[-1] == "more hello world" |
| |
| |
| def test_chdir_with_path_local(mp, tmpdir): |
| mp.chdir(tmpdir) |
| assert os.getcwd() == tmpdir.strpath |
| |
| |
| def test_chdir_with_str(mp, tmpdir): |
| mp.chdir(tmpdir.strpath) |
| assert os.getcwd() == tmpdir.strpath |
| |
| |
| def test_chdir_undo(mp, tmpdir): |
| cwd = os.getcwd() |
| mp.chdir(tmpdir) |
| mp.undo() |
| assert os.getcwd() == cwd |
| |
| |
| def test_chdir_double_undo(mp, tmpdir): |
| mp.chdir(tmpdir.strpath) |
| mp.undo() |
| tmpdir.chdir() |
| mp.undo() |
| assert os.getcwd() == tmpdir.strpath |
| |
| |
| def test_issue185_time_breaks(testdir): |
| testdir.makepyfile( |
| """ |
| import time |
| def test_m(monkeypatch): |
| def f(): |
| raise Exception |
| monkeypatch.setattr(time, "time", f) |
| """ |
| ) |
| result = testdir.runpytest() |
| result.stdout.fnmatch_lines( |
| """ |
| *1 passed* |
| """ |
| ) |
| |
| |
| def test_importerror(testdir): |
| p = testdir.mkpydir("package") |
| p.join("a.py").write( |
| textwrap.dedent( |
| """\ |
| import doesnotexist |
| |
| x = 1 |
| """ |
| ) |
| ) |
| testdir.tmpdir.join("test_importerror.py").write( |
| textwrap.dedent( |
| """\ |
| def test_importerror(monkeypatch): |
| monkeypatch.setattr('package.a.x', 2) |
| """ |
| ) |
| ) |
| result = testdir.runpytest() |
| result.stdout.fnmatch_lines( |
| """ |
| *import error in package.a: No module named {0}doesnotexist{0}* |
| """.format( |
| "'" if sys.version_info > (3, 0) else "" |
| ) |
| ) |
| |
| |
| class SampleNew(object): |
| @staticmethod |
| def hello(): |
| return True |
| |
| |
| class SampleNewInherit(SampleNew): |
| pass |
| |
| |
| class SampleOld(object): |
| # oldstyle on python2 |
| @staticmethod |
| def hello(): |
| return True |
| |
| |
| class SampleOldInherit(SampleOld): |
| pass |
| |
| |
| @pytest.mark.parametrize( |
| "Sample", |
| [SampleNew, SampleNewInherit, SampleOld, SampleOldInherit], |
| ids=["new", "new-inherit", "old", "old-inherit"], |
| ) |
| def test_issue156_undo_staticmethod(Sample): |
| monkeypatch = MonkeyPatch() |
| |
| monkeypatch.setattr(Sample, "hello", None) |
| assert Sample.hello is None |
| |
| monkeypatch.undo() |
| assert Sample.hello() |
| |
| |
| def test_issue1338_name_resolving(): |
| pytest.importorskip("requests") |
| monkeypatch = MonkeyPatch() |
| try: |
| monkeypatch.delattr("requests.sessions.Session.request") |
| finally: |
| monkeypatch.undo() |
| |
| |
| def test_context(): |
| monkeypatch = MonkeyPatch() |
| |
| import functools |
| import inspect |
| |
| with monkeypatch.context() as m: |
| m.setattr(functools, "partial", 3) |
| assert not inspect.isclass(functools.partial) |
| assert inspect.isclass(functools.partial) |