请考虑以下单元测试示例.评论几乎解释了我的问题.
[TestMethod]
public void MyTestMethod()
{
//generate some objects in the database
...
//make an assert that fails sometimes (for example purposes, this fails always)
Assert.IsTrue(false);
//TODO: how do we clean up the data generated in the database now that the test has ended here?
}
Run Code Online (Sandbox Code Playgroud)
Mik*_*ray 27
有两种方法可以做到这一点.一种是在测试类中的方法上使用TestInitialize和TestCleanup属性.它们将分别在测试之前和之后运行.
另一种方法是使用测试失败通过异常传播到测试运行器的事实.这意味着在断言失败后,可以使用测试中的try {} finally {}块来清理任何内容.
[TestMethod]
public void FooTest()
{
try
{
// setup some database objects
Foo foo = new Foo();
Bar bar = new Bar(foo);
Assert.Fail();
}
finally
{
// remove database objects.
}
}
Run Code Online (Sandbox Code Playgroud)
try/finally清理可能会变得非常混乱,有很多对象需要清理.我的团队倾向于实现IDisposable的辅助类.它跟踪已创建的对象并将其推入堆栈.调用Dispose时,项目将从堆栈中弹出并从数据库中删除.
[TestMethod]
public void FooTest()
{
using (FooBarDatabaseContext context = new FooBarDatabaseContext())
{
// setup some db objects.
Foo foo = context.NewFoo();
Bar bar = context.NewBar(foo);
Assert.Fail();
} // calls dispose. deletes bar, then foo.
}
Run Code Online (Sandbox Code Playgroud)
这具有在方法调用中包装构造函数的额外好处.如果构造函数签名发生更改,我们可以轻松修改测试代码.
小智 9
我认为在这种情况下最好的答案是仔细考虑你要测试的内容.理想情况下,单元测试应该尝试测试单个方法或函数的单个事实.当你开始将许多东西组合在一起时,它会跨越到集成测试的世界(它们同样有价值,但却不同).
对于单元测试目的,为了使您能够仅测试要测试的内容,您需要设计可测试性.这通常涉及额外使用接口(我假设您显示的代码中的.NET)和某种形式的依赖注入(但除非您需要,否则不需要IoC/DI容器).它还受益于并鼓励您在系统中创建非常有凝聚力(单一用途)和解耦(软依赖性)类.
因此,当您测试依赖于数据库中的数据的业务逻辑时,您通常会使用类似于存储库模式的东西并注入假/存根/模拟 IXXXRepository以进行单元测试.在测试具体的存储库时,您需要进行所询问的数据库清理,或者需要对基础数据库调用进行填充/存根.这真的取决于你.
当您确实需要创建/填充/清理数据库时,您可能会考虑利用大多数测试框架中提供的各种设置和拆卸方法.但要小心,因为其中一些是在每次测试之前和之后运行,这会严重影响单元测试的性能.运行速度太慢的测试不会经常运行,这很糟糕.
在MS-Test中,用于声明setup/teardown的属性是ClassInitialize,ClassCleanUp,TestInitialize,TestCleanUp.其他框架具有类似命名的构造.
有一些框架,可以帮助你的嘲讽/磕碰的:起订量,犀牛嘲笑,NMock,TypeMock,痣和存根(VS2010),VS11假货(VS11测试版)等,如果你正在寻找的依赖注入框架,看看Ninject,Unity,Castle Windsor等等.
几个回复:
如果它使用的是实际数据库,我认为它不是最严格意义上的"单元测试".这是一个集成测试.单元测试应该没有这样的副作用.考虑使用模拟库来模拟实际的数据库. Rhino Mocks是其中之一,但还有很多其他的.
但是,如果整点本次测试的是真正与数据库交互,那么你会希望与瞬态只测试数据库进行交互.在这种情况下,部分自动化测试将包括从头开始构建测试数据库的代码,然后运行测试,然后销毁测试数据库.同样,这个想法是没有外部副作用.可能有多种方法可以解决这个问题,而且我对单元测试框架不够熟悉,无法给出具体的建议.但是,如果您正在使用Visual Studio内置的测试,那么可能会使用Visual Studio数据库项目.
| 归档时间: |
|
| 查看次数: |
24567 次 |
| 最近记录: |