简体   繁体   中英

How to patch an object's attributes with `side_effect`

So I have a file some_class.py with:

class SomeReader:
    def read_path(self, url):
        return "read_path"


class SomeClass:
    def __init__(self, url):
        self.reader = SomeReader(url)
        print(self.reader.read_path(""))

And a test file some_class_test.py :

from some_class import SomeClass, SomeReader

@patch("some_class.SomeReader")
def test_some_class(mock_some_reader):
    def mock_read_path(url):
        return "mock_read_path"

    mock_some_reader.read_path.side_effect = mock_read_path

    SomeClass("")

I'm expecting that when I run this test, it will print mock_read_path but instead it prints <MagicMock name='SomeReader().read_path()' id='140701381288480'> . How do I fix this? I want to mock both the class initialization of SomeReader , hence I use @patch("some_class.SomeReader") . But I also want to mock the read_path function of SomeReader , hence I have mock_some_reader.read_path.side_effect = mock_read_path but that doesn't seem to work.

What you're doing is making a mock of the class itself, not the instances of the classes. The mock replaces call to instantiate SomeReader(url) (basically replacing the __init__ method of the class).

What you want to do is then mock the return value of the fake instance being created by SomeReader(url)

@patch("some_class.SomeReader")
def test_some_class(mock_some_reader):
    def mock_read_path(url):
        return "mock_read_path"

    mock_some_reader.return_value.read_path.side_effect = mock_read_path

    SomeClass("")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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