2015-01-01 26 views
1

我正在尝试将单元测试应用于正在处理的项目。我使用Python和MySQLdb工作,但我认为这个讨论是与语言无关的。 我想测试一个函数,我们称之为foobar()。它执行与以下类似的SQL查询:数据库连接是否应该被模拟?

cursor.execute("SELECT * FROM my_table WHERE a == " +varA+ " AND b < " +varB) 

函数中存在一点点复杂性。 cursor.execute(query)被调用的方式和频率取决于foobar的参数。

现在我不确定是否应该模拟数据库连接cursor。 如果我不这样做,这很糟糕,因为测试取决于数据库服务器的可用性。 如果我这样做,这很糟糕,因为模拟必须知道哪些查询将被调用。但确切的查询是一个实现细节。例如。查询是写成小写还是大写不影响foobar的正确性。但改变这将打破测试。由于有些复杂的模拟对象,测试也很难阅读。

这是选择较小的邪恶?有第三种方法吗?

+0

只有当这个话题很大时才有这么小的问题? – hakre

回答

0

不,您不应该模拟游标或连接。重构代码并将此代码提取到单独的服务/存储库。应该是需要行的两个参数varAvarB并返回列表的方法/对象

    你快/单元测试
  • 你应该嘲笑整个仓库 - 检查你的方法被调用合适的参数(varAvarB )。
  • 在慢/集成测试,你应该检查是否你真正数据库中嘲讽连接/光标你要做的仅仅是实现数据库正确执行这个查询所有可能varAvarB

- 它只是浪费时间

0

您已经在权衡利弊方面做得很好,但需要注意的一点是,测试的目的是模拟接近生产中可见的确切条件。

您应该避免嘲笑数据库连接并让它从本地Mysql数据库实例读取数据。此外,确保在每次测试之前db的状态被重置,以确保测试模块化。

的一般工作流程是 -

  1. 之前所有测试创建模式myApp_test,如果它不存在。
  2. 删除所有表并从模拟数据装置重新创建它们。您可以通过多种方式来完成这项工作,我最喜欢的是从YML配置文件中读取灯具并将它们直接插入到数据库中。 (如果您正在使用像rails这样的框架,它具有预先构建的功能来执行此操作,或者有其他语言的许多宝石和库可能有助于实现此目的。)
  3. 在每次测试之前,请致电在步骤2中的功能重新设定DB
  4. 运行测试

针对您的问题,我不认为这是一个问题,它依赖于一个DB可用,尤其是地方政府。如果您正在运行测试,指定您应该有可用的数据库并非不合理。或者,如果您真的关心数据库的可用性,您可以尝试使用SQLite或其他基于文本的本地数据库在本地创建自己的数据库。

+0

对真实数据库运行单元测试(即使它是为测试目的而创建的本地数据库),使它们变得缓慢而脆弱。 – buxter

相关问题