首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用post_save信号模拟django模型的方法

用post_save信号模拟django模型的方法
EN

Stack Overflow用户
提问于 2013-12-23 22:22:29
回答 1查看 2.1K关注 0票数 2

有件事我想弄清楚。对于这个“故事”模型,我有一个由post_save触发的方法。效果很好。我需要做的是弄清楚如何模拟测试,这样我就可以伪造调用并对返回进行断言。我想我需要以某种方式修补它,但我尝试了几种不同的方法,但没有取得多大的成功。我能得到的最好的是一个对象实例,但是它忽略了我传入的值。

我在我的测试中评论了我的困惑所在。任何帮助都是欢迎的。

这是我的测试:

代码语言:javascript
复制
from django.test import TestCase
from django.test.client import Client
from marketing.blog.models import Post, Tag
from unittest.mock import patch, Mock

class BlogTestCase(TestCase):
    fixtures = [
        'auth-test.json',
        'blog-test.json',
    ]

    def setUp(self):
        self.client = Client()

    def test_list(self):
        # verify that we can load the list page
        r = self.client.get('/blog/')
        self.assertEqual(r.status_code, 200)
        self.assertContains(r, "<h1>The Latest from Our Blog</h1>")
        self.assertContains(r, '<a href="/blog/javascript-date-formatting/">Simple JavaScript Date Formatting</a>')
        self.assertContains(r, 'Page 1 of 2')

        # loading a page out of range should redirect to last page
        r = self.client.get('/blog/5/', follow=True)
        self.assertEqual(r.redirect_chain, [
            ('http://testserver/blog/2/', 302)
        ])
        self.assertContains(r, 'Page 2 of 2')

        # verify that unpublished posts are not displayed
        with patch('requests') as mock_requests:
            # my futile attempt at mocking.
            # creates <MagicMock> object but not able to call return_values
            mock_requests.post.return_value = mock_response = Mock()

            # this doesn't get to the magic mock object. Why?
            mock_response.status_code = 201

            p = Post.objects.get(id=5)
            p.published = False
            # post_save signal runs here and requests is called.
            # Needs to be mocked.
            p.save()

            r = self.client.get('/blog/')
            self.assertNotContains(r, '<a href="/blog/javascript-date-formatting/">Simple JavaScript Date Formatting</a>')

下面是模型:

代码语言:javascript
复制
from django.db import models
from django.conf import settings
from django.db.models import signals
import requests

def update_console(sender, instance, raw, created, **kwargs):
    # ignoring raw so that test fixture data can load without
    # hitting this method.
    if not raw:
        update = instance

        json_obj = {
            'author': {
                'alias': 'the_dude',
                'token': 'the_dude'
            },
            'text': update.description,
        }

        headers = {'content-type': 'application/json'}

        path = 'http://testserver.com:80/content/add/'
        request = requests(path, 'POST',
            json_obj, headers=headers,
            )
        if request.status_code < 299:
            story_id = request.json().get('id')
            if story_id:
                # disconnect and reconnect signal so
                # we don't enter recursion-land
                signals.post_save.disconnect(
                    update_console,
                    sender = Story, )
                update.story_id = story_id
                update.save()
                signals.post_save.connect(
                    update_console,
                    sender = Story, )
        else:
            raise AttributeError('Error Saving to console, '+ request.text)

class Story(models.Model):
    """Lets tell a story"""
    story_id = models.CharField(
        blank=True,
        max_length=10,
        help_text="This maps to the id of the post"
    )
    slug = models.SlugField(
        unique=True,
        help_text="This is used in URL and in code references.",
    )
    description = models.TextField(
        help_text='2-3 short paragraphs about the story.',
    )

    def __str__(self):
        return self.short_headline

# add/update this record as a custom update in console
signals.post_save.connect(update_console, sender = Story)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-12-25 16:26:16

您需要在实际使用它的模块中修补requests,即

代码语言:javascript
复制
with patch('path.to.your.models.requests') as mock_requests:
    mock_requests.return_value.status_code = 200
    mock_requests.return_value.json.return_value = {'id': story_id'}
    ...

这些文档提供了关于打补丁的地方的更详细的解释

修补程序通过(临时)用另一个名称更改名称指向的对象来工作。可以有多个名称指向任何单独的对象,因此,要想进行修补工作,必须确保对被测试的系统使用的名称进行修补。 基本原则是在查找对象的位置进行修补,这不一定与定义对象的位置相同。

在这里,您需要在requests模块中修补名称models,因此需要提供它的完整路径。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20752061

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档