简体   繁体   English

如何在 python 中使用 unittest.mock 测试 class 中的 object

[英]How to replace an object inside a class being tested using unittest.mock in python

I am writing unittest for a class (MyClass) that has an instance of an object from another class (MyClient).我正在为 class (MyClass) 编写单元测试,该 class (MyClass) 具有来自另一个 class (MyClient) 的 object 实例。 I am not interested on testing MyClient so I want to replace it with an instance I can control.我对测试 MyClient 不感兴趣,所以我想用我可以控制的实例替换它。 Basically MyClient has a 'connected' property that is being invoked by MyClass.基本上 MyClient 有一个由 MyClass 调用的“已连接”属性。 Here is some code这是一些代码

my_class.py my_class.py

from my_client import MyClient

class MyClass:

 def __init__(self):
   self.client = MyClient()


 def connect(self):
   print("Connecting")
   self.client.client_connect()


 def send(self):
   if self.client.connected:
     print("Sending message")

 def is_connected(self):
   return self.client.connected

my_client.py my_client.py


class MyClient:
  def __init__(self):
    self.connected = False

  def client_connect(self):
    print("Client is connecting")
    self.connected = True

I want to test the send method, but I can't figure out how to inject a client object whose 'connected' property is set to True.我想测试发送方法,但我不知道如何注入“已连接”属性设置为 True 的客户端 object。 Similar fashion as @MockBean in Java.与 Java 中的 @MockBean 类似的方式。

Basically something of the sort:基本上是这样的:

with mock.patch("in the MyClass", "replace MyClient objects/class", "with MyMockedClass/object") as mocked:
    # then test the send method

Thanks for your help谢谢你的帮助

I found a way to get around this by replacing the class in the module with a new class.我找到了解决此问题的方法,即用新的 class 替换模块中的 class。 Using this answer I monkeypatch the my_client.MyClient class using a MockedClient by doing the following:使用这个答案,我通过执行以下操作使用 MockedClient 对 my_client.MyClient class 进行猴子补丁:

my_test.py my_test.py

class MockedClient:
  def __init__(self):
    self.connected = True 

  def client_connect(self):
    print("Mocked Connecting, but is always True ")
    self.connected = True
    print("Mocked Connected")

import my_client
my_client.MyClient = MockedClient

from my_class import MyClass

After I did that all MyClient instances are created from my MockedClient.在我这样做之后,所有 MyClient 实例都是从我的 MockedClient 创建的。 One thing to keep in mind, as mentioned in the previous answer, is to make sure you replace the class before any invocation.如上一个答案中所述,要记住的一件事是确保在任何调用之前替换 class 。 I doubt this is the best answer so I will be looking forward for a more appropriate unittesting/mock way.我怀疑这是最好的答案,所以我会期待更合适的单元测试/模拟方式。

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

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