NHibernate+WCF项目实战(二)使用NHibernate实现数据访问并进行单元测试

NHibernate+WCF项目实战 

第一篇、项目介绍与搭建

第二篇、使用NHibernate实现数据访问并进行单元测试

第三篇、使用WCF对外提供Webservices接口并进行单元测试;

第四篇、使用WAS对Webservices接口进行压力测试。

开发环境

    我的开发环境是VS2008 SP1+SQLServer 2005

    NHibernate版本是2.1.0.4000

  NUnit版本是2.5.2

  Microsoft Web Application Stress Tool 版本是1.1 

本节概要

    上一篇已经搭建了包含6个项目的解决方案,本节主要完成实体层和数据访问层的开发工作,同时使用NUnit对数据访问层中的方法进行单元测试。

准备工作

    学习NHibernate

    1)推荐系列文章NHibernate之旅

    2)博客园也刚刚成立了NHibernate专题

    您可以先从sourceforge下载本项目需要的NHibernate程序集。下载以后Required_Bins下面是必须的程序集。Required_For_LazyLoading下面是延迟加载的三种方案所需的程序集。

开发Model

using

    添加对NHibernate.dll的引用。

O/R Mapping

    Model层主要是解决O/R Mapping

    R:我们在上一篇文章中已经建立了表UserInfo。

    O:创建UserInfo对应的实体,UserInfo.cs。

   


using System;
using System.Collections.Generic;

namespace Lee.Model
{
    
/// <summary>
    
///    
    
/// </summary>
    
[Serializable]
    
public class UserInfo
    {
        
public UserInfo()
        {
            m_Id 
= 0;
            m_Name 
= null;
            m_Description 
= null;
            m_State 
= null;
        }

        private 
int m_Id;
        private string m_Name;
        private string m_Description;
        private string m_State;

        
///<summary>
        
///
        
///</summary>
        
public virtual int Id
        {
            get { 
return m_Id; }
            
set { m_Id = value; }
        }

        
///<summary>
        
///
        
///</summary>
        
public virtual string Name
        {
            get { 
return m_Name; }
            
set { m_Name = value; }
        }

        
///<summary>
        
///
        
///</summary>
        
public virtual string Description
        {
            get { 
return m_Description; }
            
set { m_Description = value; }
        }
        
///<summary>
        
///
        
///</summary>
        
public virtual string State
        {
            get { 
return m_State; }
            
set { m_State = value; }
        }
    }
}

    Mapping:创建映射文件UserInfo.hbm.xml,并设置为嵌入的资源始终复制

   

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
    
<class name="Lee.Model.UserInfo, Lee.Model" table="UserInfo">
    
    
<id name="Id" column="id" type="Int32" unsaved-value="0">
      
<generator class="native"/>
    
</id>
        
<property name="Name" type="String" column="name " />
        
<property name="Description" type="String" column="description " />
        
<property name="State" type="String" column="state " />
    
</class>
</hibernate-mapping>

开发DAL

    using

    添加对NHibernate.dll的引用。

    添加对Lee.Model项目的引用。

    创建NHibernate的Session辅助类,SessionFactory。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate;
using NHibernate.Cfg;

namespace Lee.DAL
{
    
public class SessionFactory
    
{
        
private static ISessionFactory _factory;
        
private static object obj = new object();

        
public ISession Session
        
{
            
get 
            
{
                
if (_factory == null)
                
{
                    
lock (obj)
                    
{
                        
if (_factory == null)
                        
{
                            Configuration cfg 
= new Configuration().Configure();
                            _factory 
= cfg.BuildSessionFactory();
                        }

                    }

                }

                
return _factory.OpenSession();
            }

        }

    }

}

不知道NHibernateSession怎么用的请系统学习我推荐地址的文章。我在这里就不做重复介绍了!

创建UserInfo的数据访问类UserInfoDAL

主要定义了三个方法:添加用户、修改用户信息和检查用户是否存在。

这三个方法也是WCF将要对外提供的用户操作方法,考虑到删除操作的特殊性,不对外提供删除接口。

下面是UserInfoDAL的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Lee.Model;

using NHibernate.Cfg;
using NHibernate;

namespace Lee.DAL
{
    
public class UserInfoDAL
    
{
        
private ISession _session;
        
private SessionFactory _sessionfactory = new SessionFactory();

        
/// <summary>
        
/// 添加用户
        
/// </summary>
        
/// <param name="name">用户名称</param>
        
/// <param name="description">用户描述</param>
        
/// <param name="state">状态</param>
        
/// <returns>True-操作成功|False-操作失败</returns>

        public bool AddUserInfo(string name, string description,string state)
        
{
            
if (!ExistUserInfo(name))
            
{
                UserInfo userinfo 
= new UserInfo
                
{
                    Name 
= name,
                    Description 
= description,
                    State 
= state
                }
;
                
using (_session = _sessionfactory.Session)
                
{
                    _session.Save(userinfo);
                    _session.Flush();
                }

                
return true;
            }

            
else
            
{
                
return false;
            }

            
        }

        
/// <summary>
        
/// 检查用户是否存在
        
/// </summary>
        
/// <param name="name">用户名称</param>
        
/// <returns>True-用户存在|False-用户不存在</returns>

        public bool ExistUserInfo(string name)
        
{
            
bool result = false;
            
string hql = "select count(*) from UserInfo where Name=:name";
            
using (_session = _sessionfactory.Session)
            
{
                IQuery query 
= _session.CreateQuery(hql);
                query.SetString(
"name", name);
                result 
= (int.Parse(query.UniqueResult().ToString()) == 0? false : true;
            }

            
return result;
        }

        
/// <summary>
        
/// 更新用户信息
        
/// </summary>
        
/// <param name="name">用户名称</param>
        
/// <param name="description">用户描述</param>
        
/// <param name="state">状态</param>
        
/// <returns>True-操作成功|False-操作失败</returns>

        public bool UpdateUserInfo(string name, string description, string state)
        
{
            
bool result = false;
            
if (ExistUserInfo(name))
            
{
                
string hql = "update UserInfo set Description=:description,State=:state where Name=:name";
                
using (_session = _sessionfactory.Session)
                
{
                    IQuery query 
= _session.CreateQuery(hql);
                    query.SetString(
"name", name);
                    query.SetString(
"description", description);
                    query.SetString(
"state", state);
                    result 
= (query.ExecuteUpdate() > 0? true : false;
                }

            }

            
else
            
{
                result 
= false;
            }

            
return result;
        }

    }

}

到这里我们已经完成了实体层和数据访问层的开发工作,下面我们用NUnit进行单元测试。

单元测试

    安装NUnit

        下载:http://www.nunit.org/index.php?p=download

    using

        添加对NHibernate.dll的引用。

        添加对NHibernate.ByteCode.Castle的引用。

        添加对nunit.framework的引用。

        添加对Lee.Model项目的引用。

        添加对Lee.DAL项目的引用。

    copy以下程序集到\Lee.Test\bin\Debug下

    NHibernate.dll

    NHibernate.ByteCode.Castle.dll

    Antlr3.Runtime.dll

    Iesi.Collections.dll

    log4net.dll

    Castle.DynamicProxy2.dll

    Castle.Core.dll

  测试步骤

1)创建NHibernate配置文件hibernate.cfg.xml并设置为始终复制。

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns='urn:nhibernate-configuration-2.2'>
  
<session-factory>
    
<property name="show_sql">true</property>
    
<property name="dialect">NHibernate.Dialect.MsSql2005Dialect</property>
    
<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
    
<property name="proxyfactory.factory_class">NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
    
<property name="connection.connection_string_name">SQLConnection</property>
    
<mapping assembly="Lee.Model"/>
  
</session-factory>
</hibernate-configuration>

    你需要自己配置以下节点:

     数据库连接

     <property name="connection.connection_string_name">SQLConnection</property>

    mapping

   <mapping assembly="Lee.Model"/>  

2)创建应用程序配置文件App.config,设置数据库连接。

 

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  
<connectionStrings>
    
<add name="SQLConnection" connectionString="Database=XX;User ID=sa;Password=saas;Server=XX;" providerName="System.Data.SqlClient"/>
  
</connectionStrings>
</configuration>

3)创建测试类TestUserInfoDAL

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Lee.Model;
using Lee.DAL;
using NUnit.Framework;

namespace Lee.Test
{
    [TestFixture]
    public class TestUserInfoDAL
    {
        [Test]
        public void AddUserInfo()
        {
            UserInfoDAL dal = new UserInfoDAL();
            bool result = dal.AddUserInfo("testname4", "testdesc", "teststate");
            Assert.AreEqual(true, result);
        }
        [Test]
        public void ExistUserInfo()
        {
            UserInfoDAL dal = new UserInfoDAL();
            bool result = dal.ExistUserInfo("testname");
            Assert.AreEqual(true, result);
        }
        [Test]
        public void UpdateUserInfo()
        {
            UserInfoDAL dal = new UserInfoDAL();
            bool result = dal.UpdateUserInfo("testname", "hello,testname!", "activation");
            Assert.AreEqual(true, result);
        }
    }
}

4)设置项目 Lee.Test调试时启动NUnit。

   

5)设置该项目为启动项目,在测试方法中设置断点,项目启动后,会开启NUnit。

   

    选择要测试的方法,Run即可单步调试程序了!

   如果程序出现异常或者断言结果不相等(Assert.AreEqual)会出现红色进度条。 进度条下面有异常提示。

   

    如果程序成功执行,当然就是一片绿了。

   

posted @ 2009-11-12 08:27  青羽  阅读(5288)  评论(24编辑  收藏  举报