单元测试:向数据库添加记录

时间:2011-05-19 01:37:26

标签: c# unit-testing linq-to-sql

我如何编写单元测试来测试方法将记录添加到数据库的能力?目前,我有以下内容:

[TestMethod]
public void AddUserTest()
{
    Boolean expected = true;
    Boolean result = UserManager.AddUser(test);

    Assert.AreEqual(expected, result);
}

如果我只测试将记录添加到数据库的能力(不必担心记录是否已经存在),这是正常的。但是,我不确定如何编写测试,如果由于预先存在的记录而提交失败,它仍然会通过。

如果它有所不同,我正在使用LINQ to SQL进行数据库事务。根据我在MSDN文档中收集的内容,DataContext.SubmitChanges()没有返回值,因此我也不确定如何确定特定事务是否成功。

我会继续浏览文档。 Perhaps DataContext.SubmitChanges()在单元测试中记录冲突或其他失败时抛出异常?

4 个答案:

答案 0 :(得分:6)

只要存在外部代理(例如文件系统,数据库等),它就是一个集成测试。

您的AddUserTest以上内容存在缺陷:AddUser方法可能会返回true而不添加任何内容或未正确添加它仍然返回true!在这种情况下,您没有准确测试任何东西。

编写一个集成测试,将数据添加到数据库,然后检索它并比较两组值是否相等。

答案 1 :(得分:1)

我同意Mitch(这实际上是一个集成测试)。

要处理您的方案,您可以在测试中添加ExpectionException属性。这意味着您收到预期的异常,然后测试仍然通过。

[TestMethod()]
[ExpectedException(typeof(System.Data.Linq.DuplicateKeyException))]
public static void MyTest()
{
    ....
}

如果你需要检查异常的消息,有一个有用的重载,允许你指定预期的字符串(见http://msdn.microsoft.com/en-US/library/ms243315.aspx

public ExpectedExceptionAttribute(
    Type exceptionType,
    string noExceptionMessage
)

将使用

[ExpectedException(typeof(DuplicateKeyException), "Something went wrong")]

答案 2 :(得分:0)

如果在测试运行之前启动事务,然后在测试运行后中止事务,那么您将永远不会有预先存在的数据行。

在运行前后使用[TestInitialize][TestCleanup];分别

请参阅http://msdn.microsoft.com/en-us/library/system.transactions.transactionscope.aspx

答案 3 :(得分:0)

如果记录存在,您将收到主要密钥违例异常。您可以通过更改UserManager.AddUser以通过在插入之前从数据库中选择记录来显式检查此情况来避免异常(请参阅Linq的Any()或SingleOrDefault())。如果记录返回,则显式返回false。

或者在try / catch块中将AddUser中的所有代码包装起来。在catch中返回false。

哎呀,两个都做。

另外,为什么不检查测试数据库以查看是否在测试中插入了记录?我不会把测试中的方法用于成功/失败,你不应该验证这个吗?

单元测试纯粹主义者不鼓励使用真实数据库进行单元测试。我们实际上 unit 使用模拟数据库测试我们的大部分数据库层的LinqToSql代码。谷歌“Irepository linq to sql unit test”获得了一堆结果。我从一系列博客文章中获取了大量的想法,这些博客文章将在搜索中返回,并且制作出一个令人惊讶的系统(但并非没有一些挑战)。