4

In a class, I have an attribute (self.data) which is a pandas.DataFrame.

I have a method save() in the class that basically calls self.data.to_csv() with some validations beforehand. In the test, I would like to patch this so that it won't actually store data in the directory, I just need to make sure it runs as mock.

I couldn't wrap my head around how to patch it. So far I have:

# Myclass.py

import pandas as pd
class Myclass:
    def __init__(self, data):
        self.data = pd.DataFrame(data=data)

    def save(self, path):
        # Do something validation
        # I would like to patch the line below. 
        self.data.to_csv(path)

In test_myclass.py:

from unittest import mock
import Myclass

@mock.patch(Myclass.to_csv)
def test_save(myclass_fixture):
    myclass_fixture.save(path)

I got the error:

AttributeError: type object 'Portfolio' has no attribute 'to_csv'

1 Answer 1

3

to_csv is a method of DataFrame, so you have to patch that method, as it is imported in the production code:

@patch("myproject.Myclass.pd.DataFrame.to_csv")
def test_save(patched_to_csv):
    data = some_test_data  # this may come from a fixture
    my = MyClass(data)
    my.save("some_path")
    patched_to_csv.assert_called_once()

This assumes that your project layout is myproject/Myclass.py.

Note that the first parameter to patch is not an object, but a string, containing the path to the patched object (see where to patch for what it shall contain).

It also looks like you want to take your class from a fixture - in this case you have to add this fixture to the arguments:

@pytest.fixture
def myclass_fixture():
   test_data = ...
   yield MyClass(test_data)

@patch("myproject.Myclass.pd.DataFrame.to_csv")
def test_save(patched_to_csv, myclass_fixture):
    myclass_fixture.save("some_path")
    patched_to_csv.assert_called_once()
Sign up to request clarification or add additional context in comments.

2 Comments

hmm. It actually complained Myclass has no attribute pd.
Note that Myclass here is the module name, not the class name, and by module_path_to_my_class I mean the path to the module Myclass, not the class, e.g. myproject.Myclass.pd..... I'll probably change that to make it clearer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.