我正在使用存储库模式开发 ASP MVC 3 项目,我想知道我们到底如何为存储库(聚合)上的 CRUD 操作编写单元测试。我被困在保存部分,我想回滚我的保存,将其从数据库中删除,比如
Transaction.rollback,它不适合我,任何人都可以帮我提供一些关于如何执行此操作的示例代码。
的概述
Begintransaction
session.save(Parent parent) in repository
transaction.commit.
这是我的代码Unittest
opensession;
_rep.Save(parent);
:实际上,如果有一种方法或一段代码可以放入我的测试类中的 TearDown 部分,该测试类在每次测试后运行 在 Save 方法之后在 mycase 中说并删除该特定记录,并且另一件事被认为是,因为这在每次测试后运行,所以当它尝试在其他测试方法(删除、获取全部)等之后执行相同的操作时,我不知道如何处理它,我很困惑。
I am working on ASP MVC 3 PROJECT with repository pattern, I want to know how exactly we have to write a unit test for CRUD operations on repository(aggregate). I am stuck with Saving part where I want to rollback my save, remove it from database, something like
Transaction.rollback, it i not working for me, can anyone please help me with some sample code on how to do this.
Here is the overview of my code
Begintransaction
session.save(Parent parent) in repository
transaction.commit.
Unittest:
opensession;
_rep.Save(parent);
Actually if there is a way or a piece of code that i can put into the TearDown part in my test class that runs after each test Say in mycase after Save method and deletes that particular record, and one more thing considered to be is, AS THIS RUNS AFTER EACH TEST I DNT know how to handle it when it tries to do the same thing after other test methids (delete, get all) etc.., i am all confused.
发布评论
评论(4)
首先,您应该决定这是您想要执行的经典单元测试还是涉及数据库的集成测试。如果您想测试您的实体,您应该使用注入到测试类中的假或模拟存储库(IOC 容器会很好)。因此不需要回滚(因为不涉及数据库)。如果您执行集成测试,那么我建议您使用内存数据库中的 Sqlite。它真的很轻。 Sqlite 的一个问题是它不提供事务支持。
First of all, you should decide if it's a classic unit test you want to perform or an integration test with a database involved. If you want to test your entities you should use a fake or a mock repository that you inject into your test class (IOC container would be nice). Hence there is no need for rollback (as no database is involved). If you perform an integration test, then I suggest you use an Sqlite in memory database. It's realy lightweight. One problem though with Sqlite is that it doesn't provide transaction support.
如果您想测试数据库访问,可以使用内存数据库(例如 SQLite)进行测试。当您的测试完成时,该数据库将消失,并且您不必清理测试数据。另一个优点是速度。内存数据库比 SQL Server 等快得多。
If you want to test your database access you can use an in memory database like SQLite for testing. This database will disappear when your tests are finished and you don't have to clean up the testdata. An other advantage is the speed. In memory DBs are much faster than SQL Server etc.
我想您需要回滚以保持数据库干净并避免测试之间的干扰。您可以通过为每个单元测试提供自己的数据库来实现这一点。有一篇很好的文章如何在 Sql Server 紧凑版上有效地实现这一点: http://www. differentpla.net/content/2009/03/using-sql-server-compact-edition-unit-testing。
编辑:一些示例:http://nhdatabasescopes.codeplex.com/。
I suppose that you need the rollback to keep database clean and to avoid interference between tests. You can achieve this by providing own database to each unit test. There is a nice article how to achieve this in effective way on Sql Server compact edition: http://www.differentpla.net/content/2009/03/using-sql-server-compact-edition-unit-testing.
EDIT: Some examples: http://nhdatabasescopes.codeplex.com/.
在 NUnit Setup 和 TearDown 方法中,您需要在数据库中删除并创建指定的表(使用脚本)。因此,在每次测试运行之前和之后,所有数据当然都会被删除,只留下空表供您测试。
下面的示例使用 MySql 数据库,但即使对于其他数据库,代码也应该非常相似:
上面代码中提到的脚本
createdatabase.sql
只是一个包含 drop table 和 create table 语句的 sql 文件,您可以根据您的数据库提供。以下只是一个示例:然后,您可以在 NUnit 测试类的 Setup 和 TearDown 方法中使用 DatabaseCleanup 类:
注意不要在生产环境中运行此数据库清理代码。仅在开发和测试环境中运行此类测试。
PS,我不喜欢人们在这里说使用像SqlLite这样的内存数据库。这完全违背了集成测试的全部目的。这意味着在开发环境中使用不同的数据库测试代码,然后在生产服务器上的不同数据库平台上进行部署;然后面对噩梦!
In your NUnit Setup and TearDown methods, you need to drop and then create the specified tables(using a script) in your database. So before and after each of your tests run, all your data will of-course get deleted leaving only empty tables for you to test.
The following example uses MySql database, but even for other databases, the code should be quite similar:
The script
createdatabase.sql
mentioned in the above code is simply an sql file that contains drop table and create table statements, which you can supply as per your database. Following is just a sample:You can then use the DatabaseCleanup class in your NUnit test class' Setup and TearDown methods:
Be careful not to run this database cleanup code on production environments. Run such tests on development and testing environment only.
P.S., I don't like people saying here to use in-memory databases like SqlLite. That completely defeats the whole purpose of Integration Testing. That would mean to test your code using a different database in your development environment, and then go and deploy on a different database platform on the production server; and then face a nightmare!