在类方法中模拟函数 [英] mocking a function within a class method

查看:66
本文介绍了在类方法中模拟函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在Django项目中测试类方法时模拟在类方法中调用的函数.考虑以下结构:

I want to mock a function which is called within a class method while testing the class method in a Django project. Consider the following structure:

def func():
    ...
    return resp  # outcome is a HTTPResponse object

app/models.py

from app.utils import func

class MyModel(models.Model):

    # fields

    def call_func(self):
        ...
        func()
        ...

app/tests/test_my_model.py

from django.test import TestCase
import mock    

from app.models import MyModel

class MyModelTestCase(TestCase):

    fixtures = ['my_model_fixtures.json']

    def setUp(self):
        my_model = MyModel.objects.get(id=1)

    @mock.patch('app.utils.func')
    def fake_mock(self):
        return mock.MagicMock(headers={'content-type': 'text/html'},
                              status_code=2000, 
                              content="Fake 200 Response"))

    def test_my_model(self):
        my_model.call_func()
        ...  # and asserting the parameters returned by func

当我运行测试时,将避免使用模拟函数fake_func,而是调用真正的func.我猜想mock.patch装饰器中的范围可能是错误的,但是我找不到使它起作用的方法.我该怎么办?

When I run the test the mock function fake_func is avoided and the real func is called instead. I guess the scope in the mock.patch decorator might be wrong, but I couldn't find a way to make it work. What should I do?

推荐答案

您的代码存在三个问题:

There are three problems with your code:

1)正如Daniel Roseman所提到的,您需要在调用该函数的模块上打补丁,而不是在其定义的地方打补丁.

1) As Daniel Roseman mentioned, you need to patch the module where the function is called, not where it is defined.

2)另外,您需要装饰测试方法,该方法将实际执行调用模拟函数的代码.

2) In addition, you need to decorate the test method that will actually be executing the code that calls the mocked function.

3)最后,您还需要将模拟版本作为参数传递给您的测试方法,可能是这样的:

3) Finally, you also need to pass the mocked version in as a parameter to your test method, probably something like this:

fake_response = mock.MagicMock(headers={'content-type': 'text/html'},
                          status_code=2000, 
                          content="Fake 200 Response"))


class MyModelTestCase(TestCase):

    fixtures = ['my_model_fixtures.json']

    def setUp(self):
        my_model = MyModel.objects.get(id=1)

    @mock.patch('app.models.func', return_value=fake_response)
    def test_my_model(self, fake_response):  # the mock goes in as a param or else you get number of arguments error!
        my_model.call_func()
        self.assertTrue(fake_response.called)

这篇关于在类方法中模拟函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆