模拟外部图书馆返回值抛出访问违规例外

发布于 2025-01-17 14:42:42 字数 786 浏览 0 评论 0原文

我正在使用外部库 sklearn.neighbors.KDTree 为我的方法编写 TC。

我的测试目标方法如下,

# target.py
from sklearn.neighbors import KDTree

@staticmethod
def mymethod(a, b):
    ...
    dist, index = KDTree(a).query(b, k=3)

    # manipulate the return value from KDTree.query
    ...

并且,我尝试作为TC的代码是这样的。

# mytest.py
from unittest import mock

@mock.patch('sklearn.neighbors.KDTree')
def test_mymethod(mock_kdtree):
    # make test data and set mock
    a = ...
    b = ...

    mock_kdtree.return_value.query.return_value = ...

    # execute test target
    mymethod(a, b)
   
    assert mock_kdtree.called

运行 TC 时,它会在调用 dist, index = KDTree(a).query(b, k=3) 的行上抛出异常,Windows 致命异常:访问冲突

模拟 KDTree 返回值有问题吗?

I'm writing TC for my method using external library sklearn.neighbors.KDTree.

My test target method is below,

# target.py
from sklearn.neighbors import KDTree

@staticmethod
def mymethod(a, b):
    ...
    dist, index = KDTree(a).query(b, k=3)

    # manipulate the return value from KDTree.query
    ...

and, the code I tried as TC is this.

# mytest.py
from unittest import mock

@mock.patch('sklearn.neighbors.KDTree')
def test_mymethod(mock_kdtree):
    # make test data and set mock
    a = ...
    b = ...

    mock_kdtree.return_value.query.return_value = ...

    # execute test target
    mymethod(a, b)
   
    assert mock_kdtree.called

When running TC it throws exception, Windows fatal exception: access violation on the line calling dist, index = KDTree(a).query(b, k=3).

Is there something wrong to mock KDTree return value?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

忆离笙 2025-01-24 14:42:42

它没有正确地模拟该方法。
您通常会跳过设置类的模拟实例的步骤。

from unittest import mock
import sklearn

@patch('sklearn.neighbors.KDTree')
def test_mymethod(mock_kdtree):
    # make test data and set mock
    a = ...
    b = ...
    # First create a mock instance of the kdtree class
    mock_kdtree_instance = mock.MagicMock()                                        
    mock_kdtree_instance.query.return_value = ...
    # assign this instance to the class mock
    mock_kdtree.return_value = mock_kdtree_instance
    # execute test target
    mymethod(a, b)
   
    mock_kdtree_query.assert_called()

It is not mocking the method correctly.
You typically skip the step where you set the mock instance of the class.

from unittest import mock
import sklearn

@patch('sklearn.neighbors.KDTree')
def test_mymethod(mock_kdtree):
    # make test data and set mock
    a = ...
    b = ...
    # First create a mock instance of the kdtree class
    mock_kdtree_instance = mock.MagicMock()                                        
    mock_kdtree_instance.query.return_value = ...
    # assign this instance to the class mock
    mock_kdtree.return_value = mock_kdtree_instance
    # execute test target
    mymethod(a, b)
   
    mock_kdtree_query.assert_called()
难得心□动 2025-01-24 14:42:42

对于可能遇到同样问题的人,我分享了我如何进行测试。

关键是从建议@jossefaz中使用monkeypatch。谢谢你!

# mytest.py
def test_mymethod(monkeypatch):

    class MockKDTree(object):
        def __init__(self, *fake_args):
            pass

        def query(self, *fake_args, **fake_kwargs):
            return fake_kdtree_dists, None    # This is what I wanted to return. You need to prepare.

    monkeypatch.setattr("mypackage.mymodule.KDTree", MockKDTree)

    # execute test target
    mymethod(a, b)
   
    # assertion

For someone who might be struggling with same problem, I share how I made my test.

The key is using monkeypatch, from the advice @jossefaz. Thank you!

# mytest.py
def test_mymethod(monkeypatch):

    class MockKDTree(object):
        def __init__(self, *fake_args):
            pass

        def query(self, *fake_args, **fake_kwargs):
            return fake_kdtree_dists, None    # This is what I wanted to return. You need to prepare.

    monkeypatch.setattr("mypackage.mymodule.KDTree", MockKDTree)

    # execute test target
    mymethod(a, b)
   
    # assertion

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文