2014-09-24 57 views
0

编辑1:添加了额外的功能,错过了第一次解决:在受测试模块中引入不同的模块补丁功能

这里的基本设置:

----模块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) 

----模块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()显然创建了内存数据库,但是sql文件仍然被创建,这就是所使用的 - 目前没有定义表格。日志条目显示:

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

而不是:

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

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

+0

你的补丁路径似乎是不正确的:' 'path.to.base.module.init_url''但你'init_url'是'' path.to.base.module.db.init_url''。 – 2014-09-28 00:36:08

+0

发现问题,谢谢 – 2014-10-02 15:04:55

回答

0

显然,SQLAlchemy表使用声明时不喜欢使用内存数据库。

解决方案是从使用内存数据库更改为使用数据库临时文件。

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()