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

时间:2011-03-19 17:19:36

标签: nhibernate nunit repository-pattern

我正在使用存储库模式开发ASP MVC 3 PROJECT,我想知道我们究竟是如何为存储库(聚合)上的CRUD操作编写单元测试的。我被困在保存部分,我想要回滚我的保存,从数据库中删除它,像 Transaction.rollback,它不适合我,任何人都可以帮我提供一些示例代码来解决这个问题。

以下是我的代码概述

Begintransaction
session.save(Parent parent) in repository 
transaction.commit.

单元测试:

opensession;
_rep.Save(parent);

实际上,如果有一种方法或一段代码可以放入我的测试类中的TearDown部分,该测试类在每次测试后运行在Save方法之后在mycase中说并删除该特定记录,还有一件事被认为是是这样,每次测试之后都会运行我DNT知道如何处理它,当它试图在其他测试方法之后做同样的事情(删除,得到所有)等等时,我都很困惑。

4 个答案:

答案 0 :(得分:1)

首先,您应该确定它是您要执行的经典单元测试还是涉及数据库的集成测试。如果你想测试你的实体,你应该使用你注入你的测试类的假的或模拟的存储库(IOC容器会很好)。因此不需要回滚(因为不涉及数据库)。如果您执行集成测试,那么我建议您在内存数据库中使用Sqlite。它真的很轻巧。使用Sqlite的一个问题是它不提供事务支持。

答案 1 :(得分:0)

如果要测试数据库访问权限,可以使用SQLite等内存数据库进行测试。当您的测试完成并且您不必清理testdata时,此数据库将消失。另一个优点是速度。在内存中,DB比SQL Server等快得多。

答案 2 :(得分:0)

我认为您需要回滚以保持数据库清洁并避免测试之间的干扰。您可以通过为每个单元测试提供自己的数据库来实现此目的有一篇很好的文章如何在Sql Server紧凑版上有效地实现这一点:http://www.differentpla.net/content/2009/03/using-sql-server-compact-edition-unit-testing

编辑:一些例子:http://nhdatabasescopes.codeplex.com/

答案 3 :(得分:0)

在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测试类中使用DatabaseCleanup类'设置和TearDown方法:

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

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

P.S。,我不喜欢这里的人说使用像SqlLite这样的内存数据库。这完全违背了集成测试的整个目的。这意味着在开发环境中使用不同的数据库测试代码,然后在生产服务器上的不同数据库平台上进行部署;然后面对噩梦!