This question about unit tests引发了另一件困扰我的事情。在点击数据库时,我经常以三种方式进行单元测试。
我知道选项1是进行单元测试的“正确”方式,但在三者中,这可能是我用过的最少的选项(虽然最新的项目已经与IOC一起使用,所以门对我开放)。我意识到这很大程度上取决于被嘲笑的内容和正在测试的内容,但我在这里缺少什么?
如果上下文有帮助,我在C#商店,编写内部应用程序,只有少数开发人员。
答案 0 :(得分:3)
如果您的数据访问层只暴露少数IQueryable<T>
方法,那么第一个应该不会那么难。您可以使用一个很好的技巧来伪造数据:只需将实体对象存储在List<T>
中并使用AsQueryable
。我觉得这比数据部分的moq更容易。
关于国际奥委会,我认为它目前过度使用(请注意,我的意见代表了这方面的少数程序员)。您可以在测试期间使用Moles之类的工具进行模拟,而不必滥用您的程序设计。除非设计实际上要求它,否则我不使用IOC。
答案 1 :(得分:2)
我肯定会继续使用真正的单元测试(选项1)。我喜欢斯蒂芬对此的建议。
您也可以使用实际数据库(选项2)必需进行集成测试(选项2)。为什么?因为您需要测试的部分内容(O / R映射,与实际DB模式的兼容性等)不在真正的单元测试中。
至于设置和拆卸逻辑,继承此通常就足够了(对数据库使用.NET,NUnit和SqlServer):
using System.Transactions;
using NUnit.Framework;
namespace Crown.Util.TestUtil
{
[TestFixture]
public class PersistenceTestFixture
{
public TransactionScope TxScope { get; private set; }
[SetUp]
public void SetUp()
{
TxScope = new TransactionScope();
}
[TearDown]
public void TearDown()
{
if (TxScope != null)
{
TxScope.Dispose();
TxScope = null;
}
}
}
}
很容易就是馅饼。
答案 2 :(得分:1)
对此有一整套答案。首先要做的是清楚地表达您正在测试的内容。它是一个API的外观,它背后有一个数据库,DAO对象,你的数据库结构?
实现这一目标也有助于您确定测试方法的最佳方法。从我所看到的还有你所列出的替代品。这是在内存数据库(如hsql)中启动并运行您的类和测试。这意味着您可以在测试开始时创建数据库结构。因为它在内存中你不必担心拥有数据库服务器,它很快,你可以用特定于你的测试的数据加载它。
我使用模拟器很多,虽然它们非常适合单元测试一个类,但在某些情况下它们不是。他们也很容易错过铅。对于与模拟一起工作的东西,在集成时不起作用的情况并不少见。这样做的原因是你正在加载带有某些期望和响应的模拟,你可能从模拟所代表的东西中错误地解释了它。
别误会我的意思,我喜欢嘲笑并使用它们。但是这样做你必须永远不要假设因为某些东西经过单元测试,这是正确的。它确实增加了机会,但在集成测试中实际上给你100%的保证。
答案 3 :(得分:0)
你真正测试的是什么让你觉得这很难?
如果您将业务和服务层逻辑与持久性代码分离,您应该能够轻松地隔离要进行单元测试的代码,而无需使用数据库。
单元测试最重要的原则之一是单独解耦和测试。当您清楚地了解如何执行此操作时,单元测试很容易。如果不这样做,单元测试就会变得很难。