Database 应该模拟数据库连接吗?
我正在尝试将单元测试应用到我正在从事的项目中。我使用Python和MySQLdb,但我认为这个讨论与语言无关。 我想测试一个函数,我们称它为foobar()。它执行类似以下内容的SQL查询:Database 应该模拟数据库连接吗?,database,testing,mocking,Database,Testing,Mocking,我正在尝试将单元测试应用到我正在从事的项目中。我使用Python和MySQLdb,但我认为这个讨论与语言无关。 我想测试一个函数,我们称它为foobar()。它执行类似以下内容的SQL查询: cursor.execute("SELECT * FROM my_table WHERE a == " +varA+ " AND b < " +varB) cursor.execute(“从my_表中选择*,其中a==”+varA+“和b
cursor.execute("SELECT * FROM my_table WHERE a == " +varA+ " AND b < " +varB)
cursor.execute(“从my_表中选择*,其中a==”+varA+“和b<”+varB)
函数中有一点复杂。
调用cursor.execute(query)
的方式和频率取决于foobar的参数
现在我不确定是否应该模拟数据库连接cursor
。
如果我不这样做,那就糟糕了,因为测试取决于DB服务器的可用性。
如果我这样做了,那就糟糕了,因为mock必须知道将调用哪些查询。但确切的查询是一个实现细节。例如,查询是用小写还是大写编写并不影响foobar的正确性。但改变这一点将打破考验。由于有点复杂的模拟对象,测试也很难阅读
这是一个选择较小邪恶的案例吗?还有第三种方法吗?在权衡利弊方面,您已经做得很好了,但需要注意的一点是,测试的目的是模拟尽可能接近将在生产中看到的确切条件 您应该避免模拟数据库连接,让它从本地MysQL数据库实例读取。此外,确保在每次测试之前重置db的状态,以确保测试模块化 一般的工作流程是-
myApp\u test
(如果它不存在)李>
针对您的担忧,我不认为这取决于数据库的可用性,特别是本地可用性。如果您正在运行测试,那么指定应该有一个可用的DB并不是不合理的。或者,如果您确实关心数据库的可用性,您可以尝试使用SQLite或其他基于文本的本地数据库在本地创建自己的数据库。否,您不应该模拟光标或连接。重构代码并将此代码提取到单独的服务/存储库中。应该有一个方法,它接受两个参数
varA
和varB
,并返回行/对象列表
- 在您的fast/单元测试中,您应该模拟整个存储库-检查是否使用正确的参数调用了您的方法(
和varA
)varB
- 在慢速/集成测试中,您应该检查real数据库是否正确执行了所有可能的
和varA
varB
通过模拟连接/游标,您所做的只是实现数据库-这只是浪费时间只有在主题这么大的时候才有这么一个小问题?对真实数据库运行单元测试(即使它是为测试目的创建的本地数据库)会使它们变得缓慢而脆弱。