8

我有以下功能

def main():
    (
        pd.DataFrame({'a': [1, 2, float('NaN')], 'b': [1.0, 2, 3]})
        .dropna(subset=['a'])
        .assign(
            b=lambda x: x['b'] * 2
        )
        .apply(do_something_with_each_row, axis='columns')
    )

def do_something_with_each_row(one_row):
    # do_something_with_row
    print(one_row)

在我的测试中,我想查看在所有链接操作之后构建的数据框,并在调用之前检查它是否一切正常do_something_with_each_row。最后一个函数不返回数据帧(它只是迭代所有行,类似于iterrow)。

我试图模拟这样的apply函数:

# need pytest-mock and pytest
import pandas as pd


def test_not_working(mocker):
    mocked_apply = mocker.patch.object(pd.Dataframe, 'apply')
    main()

但在这种情况下,我无法访问输入apply以测试其内容的数据框。

我还尝试模拟do_something_with_each_row

# need pytest-mock and pytest
import pandas as pd


def test_not_working_again(mocker):
    mocked_to_something = mocker.patch('path.to.file.do_something_with_each_row')
    main()

但是这次我有所有带有行参数的调用,但它们都有None值。

如何获取apply调用函数的数据帧并检查它是否确实与以下内容相同:

pd.Dataframe({'a': [1, 2], 'b': [2.0, 4]})

我正在使用0.24.2pandas 版本,升级到 pandas1.0.5并不会改变此事。

我尝试在熊猫问题中进行搜索,但没有找到有关此主题的任何内容。

4

1 回答 1

3

如果我正确理解了您的问题,这是获得您想要的行为的方法之一:

def test_i_think_this_is_what_you_asked(mocker):
    original_apply = pd.DataFrame.apply
    def mocked_apply(self, *args, **kw):
        assert len(self) == 2 # self is the pd.DataFrame at the time apply is called
        assert self.a[0] == 1
        assert self.a[1] == 3 # this will fail cause the value is 2
        assert self.b[0] == 2.0
        assert self.b[1] == 4.0
        return original_apply(self, *args, **kw)
    mocker.patch.object(pd.DataFrame, 'apply', side_effect=mocked_apply, autospec=True)
    main()
于 2020-06-25T06:57:38.853 回答