0

I am writing unittest for a class (MyClass) that has an instance of an object from another class (MyClient). I am not interested on testing MyClient so I want to replace it with an instance I can control. Basically MyClient has a 'connected' property that is being invoked by MyClass. Here is some code

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


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. Similar fashion as @MockBean in Java.

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

Oeg Bizz
  • 104
  • 6

1 Answers1

0

I found a way to get around this by replacing the class in the module with a new class. Using this answer I monkeypatch the my_client.MyClient class using a MockedClient by doing the following:

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. One thing to keep in mind, as mentioned in the previous answer, is to make sure you replace the class before any invocation. I doubt this is the best answer so I will be looking forward for a more appropriate unittesting/mock way.

Oeg Bizz
  • 104
  • 6