【发布时间】:2015-02-20 20:59:48
【问题描述】:
我是 Python 和 Django 中单元测试和模拟的新手。
这是我的模型(简化):
from django.db import models
from django.contrib.auth.models import User
class KangaUserManager(models.Manager):
def create(self, username, email, password, last_name, first_name, request, registered=True, send_confirmation=True):
kanga_user = KangaUser()
kanga_user.user = User.objects.create_user(
username=username,
email=email,
password=password,
first_name=first_name,
last_name=last_name
)
return kanga_user
class KangaUser(models.Model):
objects = KangaUserManager()
user = models.OneToOneField(User)
我想断言 User.objects.create_user 被调用,而不是实际调用它。我认为可以使用模拟库,但我什么也没做。
我试过这样的事情:
def test_create(self):
with mock.patch('django.contrib.auth.models.UserManager') as usermanager_mock:
kangauser_manager = KangaUserManager()
kangauser_manager.create(self.username, self.email, self.password, self.last_name, self.first_name, self.request, self.registered, self.send_confirmation)
self.assertTrue(usermanager_mock.create_user.called)
还有那个(还有很多我记不起来的事情:D)
def test_create(self):
with mock.patch('django.contrib.auth.models.User') as user_mock:
user_mock.objects = mock.MagicMock()
user_mock.objects.create_user = mock.MagicMock()
kangauser_manager = KangaUserManager()
kangauser_manager.create(self.username, self.email, self.password, self.last_name, self.first_name, self.request, self.registered, self.send_confirmation)
self.assertTrue(user_mock.objects.create_user.called)
但我总是看到没有调用该方法
我做错了什么?
(编辑 1:添加了一些导入)
编辑 2:
在进行 Alex martelli 建议的改编时,我偶然发现了另一个错误,
ValueError: Cannot assign "<MagicMock name='User.objects.create_user()' id='55229392'>": "KangaUser.user" must be a "User" instance.
这是修改后的代码:
from django.db import models
from django.contrib.auth import models as auth_model
class KangaUserManager(models.Manager):
def create(self, username, email, password, last_name, first_name, request, registered=True, send_confirmation=True):
kanga_user = KangaUser()
kanga_user.user = auth_model.User.objects.create_user(
username=username,
email=email,
password=password,
first_name=first_name,
last_name=last_name
)
return kanga_user
class KangaUser(models.Model):
objects = KangaUserManager()
user = models.OneToOneField(auth_model.User)
【问题讨论】:
-
您是
models.Manager的子类,但调用Users.something而不是models.User.something。这表明您的测试代码已经直接导入了User以及models,并且模拟直接导入的类(可以做到但)更难。你能改变你的测试代码来调用models.User吗?否则,您将不得不模拟User在您的测试代码中,而不是在django包层次结构中(一个典型的模拟问题,顺便说一句)。 -
我可以试试,但是问题(我没有把它放在我展示的代码中,我应该编辑它以使其更清楚,这是模型来自不同的模块,来自 django .db import models from django.contrib.auth.models import User 我将尝试使用别名进行导入。感谢您的回答
标签: python django unit-testing mocking