使用模拟补丁来模拟实例方法

发布于 2024-12-20 14:48:08 字数 814 浏览 0 评论 0原文

我试图在使用富有想象力的名称 模拟测试库测试 Django 应用程序时模拟某些内容。我似乎无法完全让它工作,我正在尝试这样做:

models.py
from somelib import FooClass
    
class Promotion(models.Model):
    foo = models.ForeignKey(FooClass)
    def bar(self):
        print "Do something I don't want!"
test.py
class ViewsDoSomething(TestCase):
    view = 'my_app.views.do_something'
    
    def test_enter_promotion(self):
        @patch.object(my_app.models.FooClass, 'bar')
        def fake_bar(self, mock_my_method):
            print "Do something I want!"
            return True
    
        self.client.get(reverse(view))

我做错了什么?

I'm trying to mock something while testing a Django app using the imaginatively named Mock testing library. I can't seem to quite get it to work, I'm trying to do this:

models.py
from somelib import FooClass
    
class Promotion(models.Model):
    foo = models.ForeignKey(FooClass)
    def bar(self):
        print "Do something I don't want!"
test.py
class ViewsDoSomething(TestCase):
    view = 'my_app.views.do_something'
    
    def test_enter_promotion(self):
        @patch.object(my_app.models.FooClass, 'bar')
        def fake_bar(self, mock_my_method):
            print "Do something I want!"
            return True
    
        self.client.get(reverse(view))

What am I doing wrong?

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

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

发布评论

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

评论(3

高冷爸爸 2024-12-27 14:48:08

要添加到 Kit 的答案中,指定 patch.object() 的第三个参数允许指定模拟对象/方法。否则,将使用默认的 MagicMock 对象。

    def fake_bar(self):
        print "Do something I want!"
        return True

    @patch.object(my_app.models.FooClass, 'bar', fake_bar)
    def test_enter_promotion(self):
        self.client.get(reverse(view))
        # Do something I want!

请注意,如果您将模拟对象指定为第三个参数,则默认的 MagicMock()不再传递到修补的对象中 - 例如不再:

def test_enter_promotion(self, mock_method):

而是改为:

def test_enter_promotion(self):

https://docs.python.org/3/library/unittest.mock.html#patch-object

To add onto Kit's answer, specifying a 3rd argument to patch.object() allows the mocked object/method to be specified. Otherwise, a default MagicMock object is used.

    def fake_bar(self):
        print "Do something I want!"
        return True

    @patch.object(my_app.models.FooClass, 'bar', fake_bar)
    def test_enter_promotion(self):
        self.client.get(reverse(view))
        # Do something I want!

Note that, if you specify the mocking object as a third argument, then the default MagicMock() is no longer passed into the patched object -- e.g. no longer:

def test_enter_promotion(self, mock_method):

but instead:

def test_enter_promotion(self):

https://docs.python.org/3/library/unittest.mock.html#patch-object

好菇凉咱不稀罕他 2024-12-27 14:48:08

啊,我对在哪里应用补丁装饰器感到困惑。固定的:

class ViewsDoSomething(TestCase):
    view = 'my_app.views.do_something'

    @patch.object(my_app.models.FooClass, 'bar')
    def test_enter_promotion(self, mock_method):
        self.client.get(reverse(view))

Ah I was confused on where to apply that patch decorator. Fixed:

class ViewsDoSomething(TestCase):
    view = 'my_app.views.do_something'

    @patch.object(my_app.models.FooClass, 'bar')
    def test_enter_promotion(self, mock_method):
        self.client.get(reverse(view))
橘亓 2024-12-27 14:48:08

如果您愿意 assert_known 等针对模拟方法,使用 patch.object 并将替换方法包装在 MagicMock(side_effect=) 中,即:

with patch.object(class_to_mock, attribute_name, \
 MagicMock(side_effect=replacement_method)) as replacement_method_mock:

例如:

from unittest.mock import patch, MagicMock

def fake_bar(self):
    print "Do something I want!"
    return True

def test_enter_promotion(self):
    with patch.object(my_app.models.FooClass, 'bar', MagicMock(side_effect=fake_bar)) as fake_bar_mock:
        self.client.get(reverse(view))
        # Do something I want!
        fake_bar_mock.assert_called()

If you'd like to do assert_called etc. against the mocked method, use the patch.object and wrap replacement method in a MagicMock(side_effect=), ie:

with patch.object(class_to_mock, attribute_name, \
 MagicMock(side_effect=replacement_method)) as replacement_method_mock:

eg.:

from unittest.mock import patch, MagicMock

def fake_bar(self):
    print "Do something I want!"
    return True

def test_enter_promotion(self):
    with patch.object(my_app.models.FooClass, 'bar', MagicMock(side_effect=fake_bar)) as fake_bar_mock:
        self.client.get(reverse(view))
        # Do something I want!
        fake_bar_mock.assert_called()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文