Django测试:如何存根model.ForeignKey属性?
我在django中有一个模型,它有一个外键指向另一个模型,在单元测试期间,我希望避免两个模型之间的紧密耦合,并为另一个模型创建一个存根,该存根每次将返回不同的值 人为的例子:Django测试:如何存根model.ForeignKey属性?,django,unit-testing,monkeypatching,Django,Unit Testing,Monkeypatching,我在django中有一个模型,它有一个外键指向另一个模型,在单元测试期间,我希望避免两个模型之间的紧密耦合,并为另一个模型创建一个存根,该存根每次将返回不同的值 人为的例子: class Moon(models.Model): def phase(self): # some extremely complex code class Wolf(models.Model): moon = models.ForeignKey(Moon) mood = model
class Moon(models.Model):
def phase(self):
# some extremely complex code
class Wolf(models.Model):
moon = models.ForeignKey(Moon)
mood = models.CharField()
def update_mood(self):
if (self.moon.phase == 'new moon'):
self.mood = "good"
if (self.moon.phase == 'waxing crescent'):
self.mood = "hopefull"
...
上述示例:
w = Wolf()
m = Moon()
# m.phase = 'new moon'
w.moon = m
w.update_mood()
w.mood # 'good'
现在,我想在执行update_mood()调用之后测试Wolf().moon属性,而实际上根本不涉及moon模型——因为它是一个非常复杂的模型,需要进入各种外部系统以确定其阶段
通常我会用猴子补丁,但既然。情绪是一种属性。。。我真的不能用猴子修补的方式来分配它
帮助。为了进行测试,您可以覆盖(monkey patch,如果您只想在测试环境中使用它)\uuuuu\getattribute\uuuu
在_uuuuGetAttribute_uuuuu检查是否调用了属性moon时,返回值或在临时变量中设置值。经过一番挖掘,偶然发现了模型add_to_class()方法,该方法执行正确的monkey修补,可以覆盖模型上的外键属性 用法示例:
class FakeMoon(object):
def get_phase(self): return self._phase
def set_phase(self, phase): self._phase = phase
phase = property(get_phase, set_phase)
# this bit is the answer to the question above
Wolf.add_to_class("moon", FakeMoon())
w = Wolf()
w.moon.phase = 'new moon'
w.update_mood()
assert w.mood == 'good'
w.moon.phase = 'waxing crescent'
w.update_mood()
assert w.mood == 'hopefull'
它不工作,w=Wolf();w、 _uuugetAttribute_uuuu=mymethod;w、 moon->从django/db/models/fields/related.py引发DoesNotExist异常。您应该在Wolf()而不是实例中验证它。def mymethod(self,key):print'getattr called for:%s'%key return getattr(self,key)setattr(Wolf,'getattribute',mymethod)w=Wolf()w.existingattr适用于普通方法,普通python,但在涉及django模型时根本不起作用。因为django模型已经使用getattribute重写,这种入侵完全破坏了模型。