2011-05-19 36 views
1

我该如何编写一个单元测试来测试方法向数据库添加记录的能力?目前,我有以下几点:单元测试:向数据库添加记录

[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()在记录冲突或其他可能在单元测试中遇到的失败时引发异常?

回答

6

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

您的AddUserTest上面有缺陷:AddUser方法可能会返回true没有添加任何东西或不正确添加它,仍然返回true!在那种情况下,你没有准确地测试任何东西。

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

+0

绝对。在直接测试物理依赖性时,基于状态的验证实际上是您唯一的选择。 – bryanbcook 2011-05-19 14:16:28

0

你会得到你抛出,如果记录存在一个主键冲突异常。您可以通过更改UserManager.AddUser来显式检查此情况,以便在插入前从数据库中选择记录(请参阅Linq的Any()或SingleOrDefault())以避免该异常。如果记录返回,则显式返回false。

或者将所有的代码放在try/catch块的AddUser中。在catch中返回false。

哎呀,两个都行。

另外,为什么不检查测试数据库以查看记录是否插入到测试中?我不会采用测试方法来评估成功/失败的方法,难道你不应该验证这一点吗?

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

1

我同意米奇(这是一个真正的集成测试)。

要处理您的情况,您可以将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")] 
+0

你也可以试试......赶上......终于阻止,并在最后做断言?我这样做了几次,只是为了确保它抛出的消息是我期望的,并断言异常的类型。 – Jon 2011-05-19 15:18:57

+0

编辑了我的答案以涵盖您的评论。你当然可以做一个finally块和断言,但我更喜欢整洁的属性。 – 2011-05-20 04:23:35