补丁功能在被测模块导入的不同模块中

时间:2014-09-24 02:47:30

标签: python-3.x mocking

编辑1:添加了第一次错过的额外功能

以下是基本设置:

---- module path.to.base.module.db:----

def init_url(...):
    <checks on opts>
    db_url = 'sqlite:///path/to/sqlite/file.sql'
    return db_url

def init_db(url, base=None):
    engine = <sqlalchemy create engine with url>
    session = <sqlalchemy create session>
    base.create_all(engine)
    return session

class Manager():
    def __init__(...):
        self.db_url = init_url(...)
        self.session = init_db(self.db_url)

---- module path.to.my.module.db:----

from path.to.base.module.db import Manager

class Projector():
   <sqlalchemy declarative table defines>

class ProjectorDB(Manager):
    super(Projector, self).__init__(...)

    def add_record(....):
        <basic checks and add record>
        if added:
            return True
        else:
            return False

----鼻子测试模块:----

from path.to.my.module.db import Projector

class test_my_db_module:
    def setUp():
        self.mocked_init_url = patch('path.to.base.module.init_url')
        self.mocked_init_url.start()
        self.mocked_init_url.return_value = 'sqlite://'
        self.projector = ProjectorDB()

    def tearDown():
        self.mocked_init_url.stop()

    def test_add_record(self):
        added = self.projector.add_record(....)

问题是,当我运行test_add_record时,我收到此错误:

'投影机没有方法“add_record()”

所以我改变了测试:

class test_my_db_module:
    def setUp():
        self.mocked_init_url = patch('path.to.base.module.init_url')
        self.mocked_init_url.start()
        self.mocked_init_url.return_value = 'sqlite://'

    def tearDown():
        self.mocked_init_url.stop()

    def test_add_record(self):
        projector = ProjectorDB()
        added = projector.add_record(....)

现在我得到:   sqalchemy:没有这样的表'Projector'

当我检查日志输出时,投影仪= Projector()显然创建了内存中的数据库,但仍然创建了sql文件,这是使用的 - 当时没有定义表。日志条目显示:

Manager.self.db_url ='sqlite://path/to/sqlite/file.sql

而不是:

Manager.self.db_url ='sqlite://'

我在什么时候不理解修补?

1 个答案:

答案 0 :(得分:0)

显然,SQLAlchemy表在使用声明时不喜欢使用内存db。

解决方案是从使用内存db更改为使用db的临时文件。

tmpfile = '/tmp/test-projectordb.sql'

class TestProjectorDB(TestCase):
    def setUp(self):
        if not hasattr(self, 'projector'):
            with patch('path.to.my.module.projectordb.init_url') as mocked_init_url:
                mocked_init_url.start()
                mocked_init_url.return_value = 'sqlite:///%s' % tmpfile
                self.projector = ProjectorDB()