我有一个从表中删除行的方法。我正在为它编写单元测试。其中一个测试用例必须在delete上导致错误条件以测试try / catch块的catch。我不能为我的生活想到如何引起错误。 ADO,EF ......任何事都可以。
由于
答案 0 :(得分:2)
我有一个从表中删除行的方法。我正在写单位 测试它。
除非该方法实际上包含可测试的内容,否则您可能只是花时间来执行框架功能。作为集成测试的一部分,没有任何问题,但它可能无法进行非常好的单元测试。
让我们假设是方法中的单元测试。隔离该功能的一种干净方法是将依赖项的模拟注入到被测试的类中。
在这种情况下,听起来依赖是ADO.Net和/或EF。其中一个模拟可以配置为抛出异常。
public class MyClass
{
private readonly IRepository _repository;
public MyClass( IRepository repository )
{
_repository = repository;
}
public void DoSomethingThatMightThrow()
{
// some logic that you want to test
// this might throw
var obj = _repository.Delete( 123 );
// some logic that you want to test
}
}
[TestMethod]
public void ATest()
{
// uses Moq framework, but any mocking framework should do this
var repository = new Mock<IRepository>();
repository.Setup( o => o.Delete( It.IsAny<int>() ) ).Throws( new DataException() );
var obj = new MyClass( repository );
obj.DoSomethingThatMightThrow();
}
我目前正在阅读The Art of Unit Testing,其中讨论了如何识别好单位。作者声称测试不必映射到单个方法,但测试应该隔离逻辑单元并且易于重复。单元测试中对数据库的依赖很少是一个好主意(同样数据访问也可以是一个很好的集成测试的一部分)。
答案 1 :(得分:1)
首先:试着像TimMedora所展示的那样嘲笑它。
但是,如果你不能,你可以通过多种方式解决这个问题,但这需要一些时间,代码,而且并不总是可行的,这取决于你的数据库引擎,数据库结构,数据库内容等等。
尝试使用与查询无关的任何方法!数据库引擎通常有大量的额外功能,可能会导致查询错误!
例如:
结果:由于未授予所需权限,因此将尝试删除任何行。
另一个例子:
RowLock(id int)
foreign key
,其目标是TestedTable的PrimaryKey 结果:现在您可以删除TestedTable中的任何行,但RowLock标记为1的行除外,并且由于FK约束,尝试删除已标记的行将中止。
您甚至可以更改测试的设置以执行额外的更改(添加用户,添加RowLock表等),然后在拆解测试后清除它(删除用户,删除RowLock表等)..但是因为我说,这一切都需要大量的工作。
我不推荐这样的方法,因为它们非常有限(rowlock只是删除/更新,权限只是每个数据库,每个表或每列等)。但它们仍然是一个很好的最后选择,因为它们具有几乎总是可能的优势 - 比如RowLock只需要DB支持已检查的FK约束。