存储库模式、NHibernate 和单元测试

发布于 2024-10-24 08:20:02 字数 524 浏览 1 评论 0 原文

我正在使用存储库模式开发 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

叫嚣ゝ 2024-10-31 08:20:02

首先,您应该决定这是您想要执行的经典单元测试还是涉及数据库的集成测试。如果您想测试您的实体,您应该使用注入到测试类中的假或模拟存储库(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.

一腔孤↑勇 2024-10-31 08:20:02

如果您想测试数据库访问,可以使用内存数据库(例如 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.

影子是时光的心 2024-10-31 08:20:02

我想您需要回滚以保持数据库干净并避免测试之间的干扰。您可以通过为每个单元测试提供自己的数据库来实现这一点。有一篇很好的文章如何在 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/.

寂寞清仓 2024-10-31 08:20:02

在 NUnit Setup 和 TearDown 方法中,您需要在数据库中删除并创建指定的表(使用脚本)。因此,在每次测试运行之前和之后,所有数据当然都会被删除,只留下空表供您测试。

下面的示例使用 MySql 数据库,但即使对于其他数据库,代码也应该非常相似:

public class DatabaseCleanup
    {
        private string _connectionString;
        private MySqlConnection _mySqlConnection;
        private string _filePath;
        public DatabaseCleanup()
        {
            _filePath = @"C:\createdatabase.sql";
            _connectionString = @"Server=localhost;Port=3306;Database=dbname;Uid=username;Password=password;";
            _mySqlConnection = new MySqlConnection(_connectionString);
        }

        public void Create()
        {
            string script = File.ReadAllText(_filePath);
            ExecuteScript(script);
        }

        private void ExecuteScript(string script)
        {
            try
            {
                MySqlCommand command = new MySqlCommand(script, _mySqlConnection);
                _mySqlConnection.Open();
                command.ExecuteNonQuery();
                _mySqlConnection.Close();
            }
            catch (Exception exception)
            {
                throw;
            }
            finally
            {
                _mySqlConnection.Close();
            }
        }
    }

上面代码中提到的脚本 createdatabase.sql 只是一个包含 drop table 和 create table 语句的 sql 文件,您可以根据您的数据库提供。以下只是一个示例:

DROP TABLE IF EXISTS `my_table`;

CREATE TABLE `my_table` (
  `Id` varchar(50) NOT NULL,
  `Name` varchar(50) NOT NULL,
  PRIMARY KEY (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

然后,您可以在 NUnit 测试类的 Setup 和 TearDown 方法中使用 DatabaseCleanup 类:

DatabaseCleanup databaseCleanup = new DatabaseCleanup();
databaseCleanup.Create();

注意不要在生产环境中运行此数据库清理代码。仅在开发和测试环境中运行此类测试。

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:

public class DatabaseCleanup
    {
        private string _connectionString;
        private MySqlConnection _mySqlConnection;
        private string _filePath;
        public DatabaseCleanup()
        {
            _filePath = @"C:\createdatabase.sql";
            _connectionString = @"Server=localhost;Port=3306;Database=dbname;Uid=username;Password=password;";
            _mySqlConnection = new MySqlConnection(_connectionString);
        }

        public void Create()
        {
            string script = File.ReadAllText(_filePath);
            ExecuteScript(script);
        }

        private void ExecuteScript(string script)
        {
            try
            {
                MySqlCommand command = new MySqlCommand(script, _mySqlConnection);
                _mySqlConnection.Open();
                command.ExecuteNonQuery();
                _mySqlConnection.Close();
            }
            catch (Exception exception)
            {
                throw;
            }
            finally
            {
                _mySqlConnection.Close();
            }
        }
    }

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:

DROP TABLE IF EXISTS `my_table`;

CREATE TABLE `my_table` (
  `Id` varchar(50) NOT NULL,
  `Name` varchar(50) NOT NULL,
  PRIMARY KEY (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

You can then use the DatabaseCleanup class in your NUnit test class' Setup and TearDown methods:

DatabaseCleanup databaseCleanup = new DatabaseCleanup();
databaseCleanup.Create();

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!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文