简体   繁体   English

如何使用 unittest.mock 调试补丁方法

[英]How to debug patched method with unittest.mock

I have the following (simplified) FBV:我有以下(简化的)FBV:

def check_existing_contacts(request):
    if request.is_ajax and request.method == "GET":
        print('Function called')
        return mailgun_validate_email(request)
    return JsonResponse({"error": "Incorrect AJAX / GET request."}, status=400)

I want to test that the mailgun_validate_email function is called:我想测试mailgun_validate_email function 是否被调用:

class TestCheckExistingContacts(TestCase):

    @patch('myapp.mailgun_validate_email')
    def test_new_contact(self, mock):
        client = Client()
        client.get('/check/', HTTP_X_REQUESTED_WITH='XMLHttpRequest')
        self.assertTrue(mock.called)
 

I am certain the test calls mailgun_validate_email as the print('Function called') displays in the console.我确定测试会调用mailgun_validate_email作为print('Function called')显示在控制台中。 However I get an assertion error that the mock.called is False .但是我得到一个断言错误, mock.calledFalse

Where am I going wrong / how can I debug this?我哪里出错了/我该如何调试?

************ UPDATE ******************* ************更新*******************

When patching the function in the same module as the view, I get the following error:在与视图相同的模块中修补 function 时,出现以下错误:

class TestCheckExistingContacts(TestCase):

    @patch('[path to views.py with check_existing_contacts].mailgun_validate_email')
    def test_new_contact(self, mock):
        client = Client()
        client.get('/check/', HTTP_X_REQUESTED_WITH='XMLHttpRequest')
        self.assertTrue(mock.called)

Results in:结果是:

Failure
Traceback (most recent call last):
  File "\tests\test_utils.py", line 123, in test_new_contact
    response = self.client.get('/validate/',
  File "\.venv\lib\site-packages\django\test\client.py", line 518, in get
    response = super().get(path, data=data, secure=secure, **extra)
  File "\.venv\lib\site-packages\django\test\client.py", line 344, in get
    return self.generic('GET', path, secure=secure, **{
  File "\.venv\lib\site-packages\django\test\client.py", line 421, in generic
    return self.request(**r)
  File "\.venv\lib\site-packages\django\test\client.py", line 496, in request
    raise exc_value
  File "\.venv\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
    response = get_response(request)
  File "\.venv\lib\site-packages\django\utils\deprecation.py", line 96, in __call__
    response = self.process_response(request, response)
  File "\.venv\lib\site-packages\django\contrib\sessions\middleware.py", line 45, in process_response
    patch_vary_headers(response, ('Cookie',))
  File "\.venv\lib\site-packages\django\utils\cache.py", line 267, in patch_vary_headers
    vary_headers = cc_delim_re.split(response['Vary'])
TypeError: expected string or bytes-like object
  1. If you did from myapp import mailgun_validate_email for check_existing_contacts , then you need to patch the reference in that module instead of myapp .如果您from myapp import mailgun_validate_emailcheck_existing_contacts了,那么您需要修补该模块中的引用而不是myapp
    Eg if the import is in myapp/views.py, then patch myapp.views.mailgun_validate_email .例如,如果导入在 myapp/views.py 中,则修补myapp.views.mailgun_validate_email
  2. The view needs to return an instance of HttpResponse or one of its subclasses, same for mailgun_validate_email since you directly return mailgun_validate_email(...) .该视图需要返回HttpResponse或其子类之一的实例,与mailgun_validate_email相同,因为您直接return mailgun_validate_email(...)
# @patch('myapp.mailgun_validate_email')                                     # Change this
@patch('myapp.views.mailgun_validate_email', return_value=JsonResponse({}))  # to this

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM