繁体   English   中英

如何在已修补的 class 的实例方法上设置副作用?

[英]How to set a side_effect on an instance method of a class that's been patched?

我如何获得@patch 'ed class 的方法以在调用时抛出异常?

B只是一个 class ,你可以调用go() on ,它反过来只是打印它发生了:

# module_b.py

class B:
  def __init__(self) -> None:
    self.x = True
    print("B constructed OK")
  def go(self):
    print("called B.go()")

A是一个 class,它包含B的一个实例。 它还有一个go()方法,它调用B实例的go()方法:

# module_a.py

from module_b import B

class A:
  def __init__(self) -> None:
    try:
      self.b = B()
      print("A constructed OK")
    except Exception as e:
      print("A's constructor threw an exception: " + repr(e))
  def go(self):
    try:
      self.b.go()
      print("b.go() called with no problems")
    except Exception as e:
      print("a.go() threw an exception: " + repr(e))

这是测试代码:

# main.py

from module_a import A
from module_b import B
from unittest import mock

# a = A()
# a.go() # output: called B.go()

@mock.patch("module_a.B") # learned the hard way to do this, not "module_b.B"
def test_b_constructor_throws(mock_b: mock.Mock):
  mock_b.side_effect = Exception("test")
  a = A()
  
print("-- test_b_constructor_throws() --")
test_b_constructor_throws()
print("")
  
@mock.patch("module_b.B.go")
@mock.patch("module_a.B")
def test_b_method_go_throws_1(
    mock_b: mock.Mock,
    mock_b_go: mock.Mock
    ):
      
  # --- attempt 1 ---
  # mock_b_go.side_effect = Exception("test")
  # a = A()
  # a.go()
  
  # --- attempt 2 ---
  mock_b.return_value.mock_b_go.side_effect = Exception("test")
  a = A()
  a.go()
  
print("-- test_b_method_go_throws_1() --")
test_b_method_go_throws_1()
print("")

最后,这是 output:

-- test_b_constructor_throws() --
B's constructor threw an exception: Exception('test')

-- test_b_method_go_throws_1() --
A constructed OK
b.go() called with no problems

Trinket.io 上的代码

我也尝试过其他各种方法,例如autospec=True和使用@patch.object()代替,但没有 go。我已经阅读了一堆看似相关的问题,但无法提出解决方案:

@jonrsharpes 的评论以及在这里阅读他的回答让我到达了我需要的地方。

  # --- attempt 1 ---
  # mock_b_go.side_effect = Exception("test")
  # a = A()
  # a.go()
  
  # --- attempt 2 ---
  # mock_b.return_value.mock_b_go.side_effect = Exception("test")
  # a = A()
  # a.go()
  
  # --- attempt 3 ---
  mock_b().go.side_effect = Exception("test")
  a = A()
  a.go()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM