【问题标题】:Django Testing: How to stub that model.ForeignKey property?Django 测试:如何存根 model.ForeignKey 属性?
【发布时间】:2011-07-27 01:14:09
【问题描述】:

我在 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 模型 - 因为它是一个非常复杂的模型,涉及到各种外部系统来计算走出它的阶段。

通常我会为此使用猴子补丁,但由于 .mood 是一个属性......我不能真正以猴子补丁的方式分配给它。

帮助。

【问题讨论】:

    标签: django unit-testing monkeypatching


    【解决方案1】:

    经过一番挖掘,偶然发现了模型 add_to_class() 方法,该方法可以进行适当的猴子修补,并且可以覆盖模型上的外键属性。

    使用示例:

    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'
    

    【讨论】:

      【解决方案2】:

      为了测试,你可以覆盖(猴子补丁,如果你只想在测试环境中使用它)__getattribute__。

      在__getattribute__中检查属性moon是否被调用,返回值或将值设置在临时变量中。

      【讨论】:

      • 它不起作用,w = Wolf(); w.__getattribute__ = 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.现有属性
      • 与普通方法、普通 python 一起工作正常——但在涉及 django 模型时根本不起作用。由于 django 模型已经使用 getattribute 覆盖,这种入侵完全破坏了模型。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-07
      • 2010-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多