开发者

Django Testing: How to stub that model.ForeignKey property?

开发者 https://www.devze.com 2023-02-21 07:08 出处:网络
I have a model in django that has a foreign key to another model, and during unit testing I want to avoid tight-coupling of the two models and create a stub for the other model that will return differ

I have a model in django that has a foreign key to another model, and during unit testing I want to avoid tight-coupling of the two models and create a stub for the other model that will return different values each time.

Contrived example:

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"
        ...

Example for the above:

w = Wolf()
m = Moon()
# m.phase = 'new moon'
w.moon = m
w.update_mood()
w.mood   # 'good'

Now I want to test the Wolf().moon property after I do an update_mood() call, without actually touching the Moon model at all - b开发者_JAVA技巧ecause its a very complex model that goes out into all kinds of external systems to figure out its phase.

Usually I would use monkey-patching for this, but since .mood is a property ... I can't really assign to it in a monkey-patching way.

Help.


With a bit of digging, stumbled on the model add_to_class() method that does proper monkey patching and can override foreign key properties on a model.

Example of usage:

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'


For the sake of testing, you could override (monkey patch, if you want to use it in test environment only) __ getattribute__.

In __ getattribute__ check if the property moon is called, return the value or set the value in a temporary var.

0

精彩评论

暂无评论...
验证码 换一张
取 消