@@ -243,6 +243,25 @@ def bar(self, arg):
243
243
assert spy .return_value == 20
244
244
245
245
246
+ def test_instance_method_spy_exception (mocker ):
247
+ excepted_message = "foo"
248
+
249
+ class Foo (object ):
250
+ def bar (self , arg ):
251
+ raise Exception (excepted_message )
252
+
253
+ foo = Foo ()
254
+ other = Foo ()
255
+ spy = mocker .spy (foo , "bar" )
256
+
257
+ with pytest .raises (Exception ) as exc_info :
258
+ foo .bar (10 )
259
+ assert str (exc_info .value ) == excepted_message
260
+
261
+ foo .bar .assert_called_once_with (arg = 10 )
262
+ assert spy .side_effect == exc_info .value
263
+
264
+
246
265
@skip_pypy
247
266
def test_instance_method_by_class_spy (mocker ):
248
267
class Foo (object ):
@@ -717,3 +736,73 @@ def test_get_random_number(mocker):
717
736
result = testdir .runpytest_subprocess ()
718
737
result .stdout .fnmatch_lines ("* 1 passed in *" )
719
738
assert "RuntimeError" not in result .stderr .str ()
739
+
740
+
741
+ def test_abort_patch_object_context_manager (mocker ):
742
+ class A (object ):
743
+ def doIt (self ):
744
+ return False
745
+
746
+ a = A ()
747
+
748
+ with pytest .raises (ValueError ) as excinfo :
749
+ with mocker .patch .object (a , "doIt" , return_value = True ):
750
+ assert a .doIt () == True
751
+
752
+ expected_error_msg = (
753
+ "Using mocker in a with context is not supported. "
754
+ "https://github.com/pytest-dev/pytest-mock#note-about-usage-as-context-manager"
755
+ )
756
+
757
+ assert str (excinfo .value ) == expected_error_msg
758
+
759
+
760
+ def test_abort_patch_context_manager (mocker ):
761
+ with pytest .raises (ValueError ) as excinfo :
762
+ with mocker .patch ("some_package" ):
763
+ pass
764
+
765
+ expected_error_msg = (
766
+ "Using mocker in a with context is not supported. "
767
+ "https://github.com/pytest-dev/pytest-mock#note-about-usage-as-context-manager"
768
+ )
769
+
770
+ assert str (excinfo .value ) == expected_error_msg
771
+
772
+
773
+ def test_abort_patch_context_manager_with_stale_pyc (testdir ):
774
+ """Ensure we don't trigger an error in case the frame where mocker.patch is being
775
+ used doesn't have a 'context' (#169)"""
776
+ import compileall
777
+
778
+ py_fn = testdir .makepyfile (
779
+ c = """
780
+ class C:
781
+ x = 1
782
+
783
+ def check(mocker):
784
+ mocker.patch.object(C, "x", 2)
785
+ assert C.x == 2
786
+ """
787
+ )
788
+ testdir .syspathinsert ()
789
+
790
+ testdir .makepyfile (
791
+ """
792
+ from c import check
793
+ def test_foo(mocker):
794
+ check(mocker)
795
+ """
796
+ )
797
+ result = testdir .runpytest ()
798
+ result .stdout .fnmatch_lines ("* 1 passed *" )
799
+
800
+ kwargs = {"legacy" : True } if sys .version_info [0 ] >= 3 else {}
801
+ assert compileall .compile_file (str (py_fn ), ** kwargs )
802
+
803
+ pyc_fn = str (py_fn ) + "c"
804
+ assert os .path .isfile (pyc_fn )
805
+
806
+ py_fn .remove ()
807
+ result = testdir .runpytest ()
808
+ result .stdout .fnmatch_lines ("* 1 passed *" )
0 commit comments