在我看来,某些代码比其他代码更容易进行单元测试。我喜欢为功能强大的代码编写单元测试(由此,我指的是主要操作其参数并返回计算结果的函数)。
但是,当代码更多地关注它的副作用时,测试它会变得更加困难。例如,我在工作中使用的套接字类具有如下声明的方法:
void Socket::Create( void );
它不带参数,并且不返回任何结果。它会抛出错误,但是底层调用(socket()
)的直接结果会被类本身隐藏。
任何人都可以推荐技术或者书籍或网站来学习更多关于单元测试代码的高级技术,主要是关于它的副作用吗?
答案 0 :(得分:4)
我会把它扔到那里,但我认为它不会对你的具体例子有所帮助。有一个称为依赖注入或控制反转的一般概念,允许您从业务逻辑中获取基础结构依赖性。因此,假设您有一个名为SubmitLoanApplication的例程,它执行验证,执行业务逻辑,并最终将数据提交到数据库。针对此运行单元测试很困难 - 但是使用IoC,您可以针对接口编写业务逻辑代码,并传入业务逻辑最终运行的该接口的实例。在您的生产代码中 - 该实例连接到数据库。在您的单元测试代码中 - 该实例是静态的,您的调用会返回可预测的结果。
答案 1 :(得分:2)
我认为你不应该关心它的作用,只是它有效。因此,您不需要测试该方法,只需要确保您尝试执行的基础操作成功。如果确实如此,那么一切都很好,如果没有,那么你需要修复一些东西。这可以测试。
我的意见可能不是“TDD”的内容,所以请把它当作它的价值。
答案 2 :(得分:1)
我不确定您是否要测试方法Socket :: Create(void)或 调用此方法的代码。 在第一种情况下,您希望为现有功能编写测试。 所以你可能想读......
http://www.objectmentor.com/resources/articles/WorkingEffectivelyWithLegacyCode.pdf
或更好的书......
http://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052
在第二种情况下,您需要一个测试双重(我们曾被允许称他们为模拟...)用于底层调用。见...
这两本书都与你提到的那种问题完全一致。 简而言之,解决方案是将问题分解为大多数功能都可以轻松测试,而且只有尽可能少的功能。答案 3 :(得分:0)
当你暴露这个时,看起来你需要在这里进行灰盒测试。
您可以将此方法视为单元测试中的黑盒子。
您可以按照预期的方式检查事情是否发生了变化。
您为此方法的失败调用设置了环境