使用输入参数对对象进行存根

时间:2009-03-10 13:00:48

标签: unit-testing testing matlab tdd stub

所以,我正在尝试存根数据库连接器以便为它编写测试。问题是数据库连接器是一个非常薄的层,对它的查询有点开放。我希望我的代码能够从数据库中请求变量,连接器应该可以正常。此调用的签名如下所示:

dim = getDimension(self,dimensionName,otherIndentifyingInformation)

(这完全在MATLAB中 - 希望答案与语言无关,或者至少在MATLAB中不可行。)

当我在我的代码中使用它时,dimensionName是存储在数据库中的一些东西之一。如果代码调用它,并且它不存在,那很好。这里的问题是我想测试一些代码,这两个代码调用getDimension,类似于:

alt = conn.getDimension('alt',otherID);
str = conn.getDimension('str',otherID);

对于(希望)显而易见的原因,altstr并不保证是相同的。事实上,他们通常不是。

所以,我的问题。如果我想将getDimension存根以返回良好的测试值,我该怎么做?创建getDimensionAlt看起来很糟糕,因为数据库中可能出现的数量有点无限,这将是一个难以维护的问题。有没有比在我的存根对象中放置逻辑更好的方法?这似乎是错误的方式......

编辑:建议设置testDB。我不是必须为每个测试用例设置一个testDB吗?在每次测试中,我都必须创建一个数据库连接,将其作为存根返回,运行测试,然后清理数据库连接。对于每个测试来说,这似乎是一个很大的开销,特别是当它甚至不是我正在测试的系统时。

我想可以设置一个testDB,每次都用适当的值填充它。那是好事吗?

编辑2:也许我的问题不清楚。我有一小段代码我试图测试。它并不比上面那两行复杂得多,而且我想干净地测试它。问题是,getDimension调用的存根取决于参数。我不需要将此存根重用于其他测试。

我认为答案可能是“在你的存根中使用简单的逻辑是可以的。”这一切都被MATLAB中没有匿名类或存根框架这一事实所困扰,所以这很难,但我想确保在我离开并在MATLAB中编写一个存根框架之前,我所做的事情在概念上是清晰的。

3 个答案:

答案 0 :(得分:0)

您是否可以设置一个具有已知值的测试数据库,然后对其执行一组已知的查询(具有已知的预期返回值)?

答案 1 :(得分:0)

如果您正在进行自动化集成测试或验收测试,我认为设置testdb是个好主意。这通常需要一次测试整个堆栈(UI,应用程序,数据库,服务等)的测试。

单元测试完全不同,它们在开发期间而不是在测试期间使用,因此它们应该更快地运行,更快地更改并且更快地编写。通常,单元测试通常只取决于他们正在测试的一小段代码。这使它们不那么脆弱,更容易理解,并使开发人员更愿意经常运行它们。

在单元测试中使用存根是个好主意。你似乎遇到的问题是,如果你想在许多测试中重复使用存根,他们的行为会变得非常复杂,在最坏的情况下,你正在重建它们应该代表的东西。如果您一次测试太多,也会发生这种情况。

解决方法是使用更小的存根,只实现一个或几个测试的行为,并让测试只测试单个行为。一次测试大量行为的测试也很有用,但它们不是单元测试,您应该将它们移动到集成测试套件(并且可以在真实数据库上运行)。我不确定matlab,但在许多语言中你都有模拟框架,你可以用来处理创建存根和为你设置行为。

答案 2 :(得分:0)

我对类似问题的回答Creating mock data for unit testing

  

您可以使用Builder类   帮助您构建实例   需要/在这种情况下你会使用   与存储库相关。有   Builder使用适当的默认值,和   在你的测试中你可以覆盖什么   你需要。这有助于您避免需要   把每个案例都放在一起   所有不同的“数据”混合在一起   测试(介绍问题,   因为通常有案例   不兼容不同   测试)。

     

更新1:看一看   www.markhneedham.com/blog/2009/01/21/c-builder-pattern-still-useful-for-test-data

同样检查此答案,关于与外部系统的整体单元测试关系:How can I improve my junit tests

请注意,有一种替代方法可以使用像dbunit这样的内存数据库。由于后面链接中提到的原因,我更喜欢构建器。