我在一家咨询公司工作,该公司使用.NET为SAP Business One开发了大量的附加组件。我想向公司介绍TDD(或至少一些好的单元测试实践)以提高代码质量。这是问题所在。
SAP提供了一个COM对象(称为Company
),可让您与SAP中的数据进行交互。 Company
是一个接口,因此它可以被模拟,但是为了让单个测试运行而必须完成的模拟量是巨大的!我已经通过一些测试试了一下,虽然它们有效但我真的必须很好地理解我正在测试的单元内部,以便创建通过的测试。我觉得这非常违背了单元测试的目的(我正在测试内部而不是接口)。
目前,通过使用依赖注入,我创建了一个Mock Company对象,该对象返回一些Mock文档,这些文档有时会根据不同的情况返回Mock值,只是为了让测试运行。有没有更好的办法?有没有人能够有效地单元测试严重依赖于某些外部库的代码?特别是当测试结果应该对那个模拟对象进行一些改变时? (比方说,当加载项运行时,应使用此Mock文档调用Mock Company对象的SaveDocument函数。)
我知道这可能是一个奇怪的问题,但事实是,为了让这些单元测试运行良好,我觉得我唯一的选择是创建一个真正的...真正的大模拟处理多个Mock文档,知道何时在合适的时间提供文档,以及许多其他事情。它基本上是在嘲笑所有的SAP。我不知道其他人在这些情况下是否还有其他最佳做法。
提前致谢!
编辑:Carl Manaster:你可能是对的。我认为问题是大多数现有的代码库都是非常程序化的。很多带有Run()方法的Windows服务。我可以肯定地看到,如果项目结构更好一些,可以更轻松地进行测试。
但是,让我们说公司不能投资重构所有这些现有项目。我应该放弃对这些东西进行单元测试的想法吗?
答案 0 :(得分:3)
如果您的方法足够短,您应该只能模拟与一个实体(公司)的交互,而不与它返回的实体进行交互。你需要的是你的方法调用(比如说)company.getDocument()。如果您的测试方法在此时与返回的文档进行了进一步的交互,请拆分该代码,以便您可以测试该代码与(模拟的)文档的交互,而无需担心该测试中的公司。听起来好像你的方法目前太长并涉及这种方法,但是如果你把它们缩小到测试一个方法只是验证调用了company.getDocument的程度,那么你会发现它更容易测试,更容易使用,最终更容易理解。
<强>更新强>
关于你是否应该放弃单元测试的问题:你想让它起作用吗?您是否对代码进行了更改?如果答案是(我认为)是肯定的,那么你应该坚持下去。您不必测试所有内容 - 而是测试您正在改变的内容。您不必重构所有内容 - 但重构您正在处理的内容,因此更容易测试并更容易更改。我提到的“削减”:用你的代码库解决你目前遇到的问题;随着时间的推移,你会发现最需要测试的代码已经过测试 - 并且它更容易使用,因为它经过了充分的测试和更好的因素。