有件事我想弄清楚。对于这个“故事”模型,我有一个由post_save触发的方法。效果很好。我需要做的是弄清楚如何模拟测试,这样我就可以伪造调用并对返回进行断言。我想我需要以某种方式修补它,但我尝试了几种不同的方法,但没有取得多大的成功。我能得到的最好的是一个对象实例,但是它忽略了我传入的值。
我在我的测试中评论了我的困惑所在。任何帮助都是欢迎的。
这是我的测试:
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>')下面是模型:
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)发布于 2013-12-25 16:26:16
您需要在实际使用它的模块中修补requests,即
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,因此需要提供它的完整路径。
https://stackoverflow.com/questions/20752061
复制相似问题