Python 单元测试模拟熊猫到

Python 单元测试模拟熊猫到,python,pandas,export-to-csv,python-unittest,Python,Pandas,Export To Csv,Python Unittest,mymodule.py def write_df_to_csv(self, df, modified_fn): new_csv = self.path + "/" + modified_fn df.to_csv(new_csv, sep=";", encoding='utf-8', index=False) class TestMyModule(unittest.TestCase): def setUp(self):

mymodule.py

def write_df_to_csv(self, df, modified_fn):
    new_csv = self.path + "/" + modified_fn
    df.to_csv(new_csv, sep=";", encoding='utf-8', index=False)
class TestMyModule(unittest.TestCase):
    def setUp(self):
        args = parse_args(["-f", "test1"])
        self.mm = MyModule(args)
        self.mm.path = "Random/path"

    self.test_df = pd.DataFrame(
                [
                    ["bob", "a"],
                    ["sue", "b"],
                    ["sue", "c"],
                    ["joe", "c"],
                    ["bill", "d"],
                    ["max", "b"],
                ],
                columns=["A", "B"],
            )

def test_write_df_to_csv(self):
    to_csv_mock = mock.MagicMock()
    with mock.patch("project.mymodule.to_csv", to_csv_mock, create=True):
        self.mm.write_df_to_csv(self.test_df, "Stuff.csv")
    to_csv_mock.assert_called_with(self.mm.path + "/" + "Stuff.csv")
测试我的模块.py

def write_df_to_csv(self, df, modified_fn):
    new_csv = self.path + "/" + modified_fn
    df.to_csv(new_csv, sep=";", encoding='utf-8', index=False)
class TestMyModule(unittest.TestCase):
    def setUp(self):
        args = parse_args(["-f", "test1"])
        self.mm = MyModule(args)
        self.mm.path = "Random/path"

    self.test_df = pd.DataFrame(
                [
                    ["bob", "a"],
                    ["sue", "b"],
                    ["sue", "c"],
                    ["joe", "c"],
                    ["bill", "d"],
                    ["max", "b"],
                ],
                columns=["A", "B"],
            )

def test_write_df_to_csv(self):
    to_csv_mock = mock.MagicMock()
    with mock.patch("project.mymodule.to_csv", to_csv_mock, create=True):
        self.mm.write_df_to_csv(self.test_df, "Stuff.csv")
    to_csv_mock.assert_called_with(self.mm.path + "/" + "Stuff.csv")
当我运行此测试时,我得到:

FileNotFoundError: [Errno 2] No such file or directory: 'Random/path/Stuff.csv'

我试图在我的方法中将
模拟为\u csv
。我的其他测试按预期运行,但是我不确定这个测试哪里出了问题。我使用MagicMock是正确的,还是忽略了其他内容?

必须以正斜杠开始路径。以下是更正后的代码:

self.mm.path = "/Random/path/"
也改变了:

to_csv_mock.assert_called_with(self.mm.path + "Stuff.csv")

Edit:正如@Thomas所说,我不确定
project.mymodule.to\u csv
是否正确

您没有提供一个最小的、可复制的示例,所以我不得不去掉一些东西来实现这一点。我想你可以自己补上缺的部分

一个问题是
mock.patch(“project.mymodule.to_csv”,…)
试图在导入路径
project.mymodule
处将模块中名为
的类模拟为_csv
。这仅仅是因为您通过了
create=True
,才“起作用”,但当然,模仿以前不存在的东西没有效果,因为没有人会调用它

您可以使用
mock.patch(“pandas.DataFrame”,…)
模拟整个
DataFrame
类。注意:无论您如何(甚至是否)在当前模块中导入
pandas
,它都不是
pd

但是您的单元测试将断言在任何
数据帧
上调用了
to_csv
,而不一定是您传入的数据帧。通过在传递给
write_df_to_csv
数据帧
对象上模拟
to_csv
方法,测试变得更全面,也更容易理解。我们可以使用
mock.patch.object
来实现这一点

mock.patch.object
返回mock函数,我们随后可以调用断言。因为它是一个方法模拟,而不是一个自由函数,所以我们不需要在断言中传递
self
参数

project/mymodule.py

def write_df_to_csv(self, df, modified_fn):
    new_csv = self.path + "/" + modified_fn
    df.to_csv(new_csv, sep=";", encoding='utf-8', index=False)
class TestMyModule(unittest.TestCase):
    def setUp(self):
        args = parse_args(["-f", "test1"])
        self.mm = MyModule(args)
        self.mm.path = "Random/path"

    self.test_df = pd.DataFrame(
                [
                    ["bob", "a"],
                    ["sue", "b"],
                    ["sue", "c"],
                    ["joe", "c"],
                    ["bill", "d"],
                    ["max", "b"],
                ],
                columns=["A", "B"],
            )

def test_write_df_to_csv(self):
    to_csv_mock = mock.MagicMock()
    with mock.patch("project.mymodule.to_csv", to_csv_mock, create=True):
        self.mm.write_df_to_csv(self.test_df, "Stuff.csv")
    to_csv_mock.assert_called_with(self.mm.path + "/" + "Stuff.csv")
def将df写入csv(df,文件名):
df.to_csv(文件名,sep=“;”,编码='utf-8',索引=False)
项目/测试\u mymodule.py

def write_df_to_csv(self, df, modified_fn):
    new_csv = self.path + "/" + modified_fn
    df.to_csv(new_csv, sep=";", encoding='utf-8', index=False)
class TestMyModule(unittest.TestCase):
    def setUp(self):
        args = parse_args(["-f", "test1"])
        self.mm = MyModule(args)
        self.mm.path = "Random/path"

    self.test_df = pd.DataFrame(
                [
                    ["bob", "a"],
                    ["sue", "b"],
                    ["sue", "c"],
                    ["joe", "c"],
                    ["bill", "d"],
                    ["max", "b"],
                ],
                columns=["A", "B"],
            )

def test_write_df_to_csv(self):
    to_csv_mock = mock.MagicMock()
    with mock.patch("project.mymodule.to_csv", to_csv_mock, create=True):
        self.mm.write_df_to_csv(self.test_df, "Stuff.csv")
    to_csv_mock.assert_called_with(self.mm.path + "/" + "Stuff.csv")
将unittest.mock导入为mock
导入单元测试
作为pd进口熊猫
将project.mymodule作为mm导入
类TestMyModule(unittest.TestCase):
def测试_写入_df_至_csv(自我):
test_df=pd.DataFrame(…)
使用mock.patch.object(test_df,“to_csv”)作为\u csv\u mock:
mm.将文件写入csv(测试文件,“Stuff.csv”)
to_csv_mock.assert_调用_with(“Stuff.csv”)
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
unittest.main()
输出

测试现在以正确的方式失败,因为参数实际上不匹配

$ python -m project.test_mymodule
F
======================================================================
FAIL: test_write_df_to_csv (__main__.TestMyModule)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/project/test_mymodule.py", line 25, in test_write_df_to_csv
    to_csv_mock.assert_called_with("Stuff.csv")
  File "/usr/lib/python3.8/unittest/mock.py", line 913, in assert_called_with
    raise AssertionError(_error_message()) from cause
AssertionError: expected call not found.
Expected: to_csv('Stuff.csv')
Actual: to_csv('Stuff.csv', sep=';', encoding='utf-8', index=False)

----------------------------------------------------------------------
Ran 1 test in 0.003s

FAILED (failures=1)

我改了,还是一样的错误message@pymat检查它现在是否工作不,我在Mac上。哦,好的,我必须检查Mac路径的格式我更新了我的答案,检查它是否工作
project.mymodule.to_csv
与Pandas的
DataFrame
to_csv
方法不同,是吗?@Thomas,我相信这与df的df部分有关。谢谢你。实际上,我修改了最后一行:to_csv_mock.assert_调用了(self.mm.path++“/”++“Stuff.csv”,sep=“;”,encoding='utf-8',index=False)