使用数据进行ASP.NET MVC单元测试

6
我们有一个非常数据驱动的应用程序。我们希望对该应用程序进行单元测试,但开发人员不愿意构建完全假的存储库,因为数据量太大。我不怪他们。
请理解,我们正在对现有应用程序进行测试。如果我们从头开始,我们会进行大量架构更改,以便更好地使用虚拟存储库进行单元测试。
我们希望在测试中分发已知的 MDF 文件,将其复制并用于执行我们的测试。是否有这方面的批准技术?我熟悉将资源嵌入测试 DLL,但不熟悉将 MDF 嵌入其中,如果可能的话。
解决方法(有点):
最终我采用了 Andrew Tokeley 在模拟 Linq 数据上下文的文章中提到的 DataContextWrapper,并创建了一个名为 FakeDataContext.cs 的文件,它基本上是一堆列表。
我编写了一个真正野蛮的 T4 模板(类似于“从 <#=table.BaseClass.QualifiedName#> 中选择 *”),以从一个已知的良好数据库中复制数据,创建一个包含许多内容的巨大类。
List<Customer> _customers = new List<Customer>();
_customers.Add(new Customer(){CustomerId = 1, CustomerName = "ACME"});

这个类有25K行代码,但由于t4写了所有这些代码,谁在乎呢?它允许我们模拟数据上下文,因此我们可以对假上下文测试我们的linq查询,并且有一定的保证我们得到了正确的查询结果。原始开发人员在仓库中放置了大量业务逻辑,因此它允许我们针对已知的良好数据测试逻辑。


1
你所需要的是进行集成测试的方法,@Jakub已经提供了一个很好的答案。你使用的是哪个测试框架? - mkchandler
我们使用Vanilla VS 2010来驱动我们的单元(小集成?)测试。这些测试包括:会员层是否在5次错误密码后正确锁定帐户?此外,我们还使用了大量Selenium来验证整个过程从头到尾都能正常工作。 - Code Silverback
2个回答

5

您能在共享服务器上设置测试数据库,以便无需部署mdf文件吗?

此外,您能将所有单元测试都用TransactionScope包装起来吗?

我在公司中使用了一个测试数据库,其中包含了所有测试的已知参考数据,并创建了一个集成测试的基类:

[TestClass]
public class ServiceTest
{
    private TransactionScope Transaction { get; set; }

    [TestInitialize]
    public virtual void TestInitialize()
    {
        Transaction = new TransactionScope();
    }

    [TestCleanup]
    public virtual void TestCleanup()
    {
        Transaction.Dispose();
    }
}

每个测试都会回滚它所做出的所有更改,因此不会有测试数据污染数据库的问题。

1
从技术角度来说,这些被称为“集成测试”。这是我在项目中使用的方法,效果非常好! - mkchandler
需要注意的是,xUnit 提供了一种内置的方法来实现这一点:http://xunit.codeplex.com/ - mkchandler
我们采用这种方法。我建议使用这种方法而不是伪造存储库。你想伪造一个有10,000行的存储过程吗? :) - bzlm

0

你有没有看过一个模拟框架?如果你的代码编写得足够好,可以在单元测试中将数据依赖项注入到对象中,那么你应该能够模拟这些数据依赖项。

我用 Moq 取得了巨大的成功,但那是因为我一开始就采用了依赖注入的方式编写代码。


Brian提到这个应用程序非常依赖数据 - 我想模拟(一种很好的实践)可能不是很可行。我曾经在一个应用程序上工作,该应用程序从数据库中使用了大量数据,并且逻辑分散在许多类/服务中,如果没有先重写它,那么模拟它将是不可能的;-) - Jakub Konecki
是的,这很混乱。我们尽可能使用moq,但是虚假数据的数量实在太多了。我们正在注入数据依赖项,但是虚假存储库正在变得越来越庞大。 - Code Silverback

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接