One thing I'm trying out right now is (a) writing all of my business logic in module files; (b) breaking up that logic into small-ish classes that each seem to have with around 5-10 methods each; (c) injecting my dependencies as much as possible into the class in the __init__ method and then passing them from __init__ to the class methods. This seems to make it much easier to mock external dependencies. So, for example, rather than performing a db select in a method, I might do something like this:
class Myclass(object): def __init__(self, myrows=None, other_class_instance=None): if myrows is None: db = current.db myrows = db(db.mytable.id > 0).select() self.myrows = myrows if other_class_instance is None: other_class_instance = OtherClassInstance() self.other_class_instance = other_class_instance def my_method(self, target) person = self.myrows.find(lambda row: row.id == target) bday = self.other_class_instance.get_birthday() if person.birthday = bday return 'Happy Birthday!' else: return 'No cake for you!' In order to test this class all I have to provide is something that looks like a Rows object and something that looks like an instance of another class. If I pass those mocked objects at class instantiation, I override the default calls to db and the external class in __init__() and my class is effectively decoupled for testing. I can even run tests on this class (should I want to) without the web2py environment. I should add that I've just been reading a lot about tdd and testing in general, so there's a good chance I'm passing on flawed advice here. :) But it's working for me so far. The dependency injection idea can be taken to extremes, with decorators and whole "frameworks" but for my purposes the simple approach taken here seems functional. The other advantage of this is that your classes and methods become much more abstract and so much easier to reuse in other projects. Or if (perish the thought) you someday wanted to refactor your app using Django or something you could use a class like this largely untouched, as long as you pass an alternative for db in to the class constructor. Cheers, Ian On Wednesday, October 3, 2012 3:46:03 PM UTC-4, viniciusban wrote: > > Hi all. > > I continue diving into unit-testing and I'd like to know how do you > organize your applications to be unit-tested. > > Thin controllers? DAO classes? How do you decouple things in web2py to > make unit-testing easy? > > -- > Vinicius Assef > --