Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django测试:如何存根model.ForeignKey属性?_Django_Unit Testing_Monkeypatching - Fatal编程技术网

Django测试:如何存根model.ForeignKey属性?

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

我在django中有一个模型,它有一个外键指向另一个模型,在单元测试期间,我希望避免两个模型之间的紧密耦合,并为另一个模型创建一个存根,该存根每次将返回不同的值

人为的例子:

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重写,这种入侵完全破坏了模型。