Logo

NHibernate

The object-relational mapper for .NET

NHibernate Bootstrapper: Unit Tests and Project References

This post is the second one about the NHibernate Bootstrapper. The first is located here. The first post set up the project structure, introduced the generic DAO, and demonstrated the SessionPerRequest implementation in an IHttpModule. This post will factor the reference to NHibernate out of the web application project and cover some unit testing techniques.  Programmers that are not familiar with SOLID should review the Wikipedia page and the references there. The first post noted that the version of NHibernate Bootstrapper presented there was not suitable for use in anything other than a demonstration program. The version of the solution discussed in this post is suitable for use in a small-scale system where there no more than 15 classes involved. The version following this post should be suitable for even the largest deployments, though there will be at least one additional post that refines the capabilities of an enterprise ready solution. The project sources are in a zip file located here and are updated to use the NHibernate 3.0.0 GA release.

PresentationManager

The solution in the first post used NHibernate references in the web application project. In this version of the solution those references have been moved to the presenter project. Now the solution is taken on the characteristics of the Model-View-Presenter (MVP) , discussed by Martin Fowler here, and later refined into a Supervising Presenter and Passive View. The solution employed here follows the Passive View pattern, where the view has no direct interaction with the model. The solution builds on 2 Code Project articles, originally released in Jul 2006. The first reference used is Model View Presenter with ASP.Net by Bill McCafferty and the second is Advancing the Model-View-Presenter Pattern – Fixing the Common Problems by Acoustic. There are a number of reasons for using the MVP pattern, but the most important of them is the enabling of testing. The second half of this post will show how it becomes possible to test the code behind of an aspx page.

In the first post the BusinessServices project, that would hold the presenters, was empty. Now there is a Presentation Manager and a Presenter classes. The PresentationManager is able to register the view of the ASP.Net page and associate it with the correct presenter. It is also remarkable in that it automatically instantiates the correct presenter for use by the ASP.Net page. This is done in the LoadPresenter method. The auto-instantiation is how ASP.Net pages are able to function with only a reference to the PresenterTypeAttribute in the web application project.

 

 

PresentationManager.cs
  1. using System;
  2. using Infrastructure;
  3.  
  4. namespace BusinessServices
  5. {
  6.     public static class PresentationManager
  7.     {
  8.         public static T RegisterView<T>(Type presenterType, IView myView) where T : Presenter
  9.         {
  10.             return RegisterView<T>(presenterType, myView, null);
  11.         }
  12.  
  13.         public static T RegisterView<T>(Type presenterType, IView view, IHttpSessionProvider httpSession) where T : Presenter
  14.         {
  15.             return (LoadPresenter(presenterType, view, httpSession)) as T;
  16.         }
  17.  
  18.         public static void RegisterView(Type presenterType, IView view)
  19.         {
  20.             RegisterView(presenterType, view, null);
  21.         }
  22.  
  23.         public static void RegisterView(Type presenterType, IView view, IHttpSessionProvider httpSession)
  24.         {
  25.             LoadPresenter(presenterType, view, httpSession);
  26.         }
  27.  
  28.         private static Object LoadPresenter(Type presenterType, IView view, IHttpSessionProvider httpSession)
  29.         {
  30.             int arraySize = ((httpSession == null) ? 1 : 2);
  31.             Object[] constructorParams = new Object[arraySize];
  32.  
  33.             constructorParams[0] = view;
  34.  
  35.             if (arraySize.Equals(2))
  36.             {
  37.                 constructorParams[1] = httpSession;
  38.             }
  39.             return Activator.CreateInstance(presenterType, constructorParams);
  40.         }
  41.  
  42.     }
  43. }

 

 

 

The PresenterTypeAttribute is what each page uses to drive SelfRegister. This is the mechanism that ties the individual web pages to the appropriate presenter in an automated fashion. This is one aspect of a poor man’s Inversion of Control without requiring a separate container to hold the various dependencies.

 

PresenterTypeAttribute.cs
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5.  
  6. namespace BusinessServices
  7. {
  8.     //[AttributeUsage(AttributeTargets.All, Inherited = true)]
  9.     public class PresenterTypeAttribute : Attribute
  10.     {
  11.         private Type _presenterType;
  12.  
  13.         public PresenterTypeAttribute(Type presenterType)
  14.         {
  15.             _presenterType = presenterType;
  16.         }
  17.  
  18.         public Type PresenterType
  19.         {
  20.             get { return _presenterType; }
  21.             set { _presenterType = value; }
  22.         }
  23.     }
  24. }

 

Revised Web Application Project

The code behind for the web page has been revised to work with a presenter. You will note that a large amount of code that was in the original code behind file has now been commented out, as it has been revised slightly and moved to the the PersonPresenter class. The code behind file is now left with just event declarations, a number of properties and the occasional method for working with gridview or dropdown controls and the Page_Load event. All that remains in the code behind are methods and properties that are referencing System.Web, while the various presenter classes have no reference to System.Web. It is important to note that the removal of the reference to System.Web in the presenter classes is what enables a high degree of code coverage in the Unit Tests.

Default.aspx.cs (Part 1)
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Web.UI;
  4. using System.Web.UI.WebControls;
  5. using BusinessServices;
  6. using BusinessServices.Interfaces;
  7. using BusinessServices.Presenters;
  8. using DataServices.Person;
  9.  
  10. namespace WebNHibernate
  11. {
  12.     [PresenterType(typeof(PersonPresenter))]
  13.     public partial class _Default : BasePage, IPersonView
  14.     {
  15.  
  16.         public event GridViewBtnEvent OnEditCommand;
  17.         public event GridViewBtnEvent OnDeleteCommand;
  18.         public event EmptyBtnEvent OnRefreshPersonGrid;
  19.         public event EmptyBtnEvent OnSaveEditPerson;
  20.         public event EmptyBtnEvent OnClearEditPerson;
  21.         //added event for presenter
  22.         public event EmptyEvent OnPageLoadNoPostback;
  23.  
  24.         //private ISession m_session = null;
  25.  
  26.         protected void Page_Load(object sender, EventArgs e)
  27.         {
  28.             //added for the presenter
  29.             base.SelfRegister(this);
  30.  
  31.             //OnEditCommand += new GridViewBtnEvent(_view_OnEditCommand);
  32.             //OnDeleteCommand += new GridViewBtnEvent(_view_OnDeleteCommand);
  33.             //OnRefreshPersonGrid += new EmptyBtnEvent(_view_OnRefreshPersonGrid);
  34.             //OnSaveEditPerson += new EmptyBtnEvent(_view_OnSaveEditPerson);
  35.             //OnClearEditPerson += new EmptyBtnEvent(_view_OnClearEditPerson);
  36.  
  37.             //if (m_session == null)
  38.             //    m_session = SessionManager.SessionFactory.GetCurrentSession();
  39.  
  40.             if (!Page.IsPostBack)
  41.             {
  42.                 //added line below for presenter
  43.                 OnPageLoadNoPostback();
  44.                 //IList<PersonDto> gvData = Get_PersonData();
  45.                 //Fill_gvPerson(gvData);
  46.             }
  47.            
  48.         }
Default.aspx.cs (Part 2)
  1. protected void gvPerson_OnRowCommand(object sender, GridViewCommandEventArgs e)
  2. {
  3.     Guid id = new Guid(gvPerson.DataKeys[Convert.ToInt32(e.CommandArgument)].Value.ToString());
  4.     if (e.CommandName == "EditRow")
  5.         OnEditCommand(id);
  6.     else if (e.CommandName == "DeleteRow")
  7.         OnDeleteCommand(id);
  8. }
  9.  
  10. //public void _view_OnEditCommand(Guid id)
  11. //{
  12. //    if (m_session == null)
  13. //        m_session = SessionManager.SessionFactory.GetCurrentSession();
  14.  
  15. //    PersonDAOImpl dao = new PersonDAOImpl(m_session);
  16. //    Person pers = dao.GetByID(id);
  17.  
  18. //    txtPersonIdValue = pers.Id.ToString();
  19. //    txtFirstNameValue = pers.FirstName;
  20. //    txtLastNameValue = pers.LastName;
  21. //    txtEmailValue = pers.Email;
  22. //    txtUserIdValue = pers.UserID;
  23.  
  24. //    pers = null;
  25. //    dao = null;
  26. //}
  27.  
  28. //public void _view_OnDeleteCommand(Guid id)
  29. //{
  30. //    if (m_session == null)
  31. //        m_session = SessionManager.SessionFactory.GetCurrentSession();
  32.  
  33. //    PersonDAOImpl dao = new PersonDAOImpl(m_session);
  34. //    using (var tx = m_session.BeginTransaction())
  35. //    {
  36. //        dao.Delete(id);
  37. //        tx.Commit();
  38. //    }
  39.  
  40. //    dao = null;
  41. //    _view_OnRefreshPersonGrid();
  42. //}
Default.aspx.cs (Part 3)
  1. //public void _view_OnRefreshPersonGrid()
  2. //{
  3. //    IList<PersonDto> gvData = Get_PersonData();
  4. //    Fill_gvPerson(gvData);
  5. //}
  6.  
  7. //public void _view_OnSaveEditPerson()
  8. //{
  9.  
  10. //    if (m_session == null)
  11. //        m_session = SessionManager.SessionFactory.GetCurrentSession();
  12.  
  13. //    Guid editId = new Guid();
  14. //    Person editPers = new Person();
  15.  
  16. //    if (!string.IsNullOrEmpty(txtPersonIdValue))
  17. //        editId = new Guid(txtPersonIdValue);
  18.  
  19. //    PersonDAOImpl dao = new PersonDAOImpl(m_session);
  20. //    using (var tx = m_session.BeginTransaction())
  21. //    {
  22. //        if (editId.ToString().Length == 36)
  23. //            editPers = dao.GetByID(editId);
  24. //        editPers.FirstName = txtFirstNameValue;
  25. //        editPers.LastName = txtLastNameValue;
  26. //        editPers.Email = txtEmailValue;
  27. //        editPers.UserID = txtUserIdValue;
  28.  
  29. //        editPers = dao.Save(editPers);
  30. //        tx.Commit();
  31. //    }
  32.  
  33. //    editPers = null;
  34. //    dao = null;
  35. //    _view_OnRefreshPersonGrid();
  36. //    _view_OnClearEditPerson();
  37. //}
  38.  
  39. //public void _view_OnClearEditPerson()
  40. //{
  41. //    txtPersonIdValue = null;
  42. //    txtFirstNameValue = null;
  43. //    txtLastNameValue = null;
  44. //    txtEmailValue = null;
  45. //    txtUserIdValue = null;
  46. //}
Default.aspx.cs (Part 4)
  1. protected void btnRefresh_Click(object sender, EventArgs e)
  2. {
  3.     OnRefreshPersonGrid();
  4. }
  5.  
  6. protected void btnSave_Click(object sender, EventArgs e)
  7. {
  8.     OnSaveEditPerson();
  9. }
  10.  
  11. protected void btnClear_Click(object sender, EventArgs e)
  12. {
  13.     OnClearEditPerson();
  14. }
  15.  
  16. public void Fill_gvPerson(IList<PersonDto> data)
  17. {
  18.     gvPerson.DataSource = data;
  19.     gvPerson.DataBind();
  20. }
  21.  
  22. //public IList<PersonDto> Get_PersonData()
  23. //{
  24. //    IList<PersonDto> retVal = null;
  25.  
  26. //    if (m_session == null)
  27. //        m_session = SessionManager.SessionFactory.GetCurrentSession();
  28.  
  29. //    ICriteria crit = m_session.CreateCriteria(typeof(Person));
  30. //    PersonDAOImpl dao = new PersonDAOImpl(m_session);
  31.  
  32. //    IList<Person> people = dao.GetByCriteria(crit);
  33. //    retVal = (from person in people
  34. //              select new PersonDto
  35. //                  {
  36. //                      PersonID = person.Id,
  37. //                      FirstName = person.FirstName,
  38. //                      LastName = person.LastName,
  39. //                      Email = person.Email,
  40. //                      UserID = person.UserID
  41. //                  }).ToList<PersonDto>();
  42. //    crit = null;
  43. //    dao = null;
  44. //    people = null;
  45.  
  46. //    return retVal;
  47. //}
Default.aspx.cs (Part 5)
  1.         public string txtPersonIdValue
  2.         {
  3.             get { return txtPersonID.Text; }
  4.             set { txtPersonID.Text = value; }
  5.         }
  6.  
  7.         public string txtFirstNameValue
  8.         {
  9.             get { return txtFirstName.Text; }
  10.             set { txtFirstName.Text = value; }
  11.         }
  12.  
  13.         public string txtLastNameValue
  14.         {
  15.             get { return txtLastName.Text; }
  16.             set { txtLastName.Text = value; }
  17.         }
  18.  
  19.         public string txtEmailValue
  20.         {
  21.             get { return txtEmail.Text; }
  22.             set { txtEmail.Text = value; }
  23.         }
  24.  
  25.         public string txtUserIdValue
  26.         {
  27.             get { return txtUserID.Text; }
  28.             set { txtUserID.Text = value; }
  29.         }
  30.  
  31.     }
  32. }

BasePage

The web project has had a BasePage class added to reuse element and methods common to more than just a single web page. This includes the SelfRegister method and various properties for RequestString, RequestUrl and IsPostBack. These are sample functions which have common utility throughout all the web pages. It is here that additional utility methods and functions with similar commonality would be added.

BasePage.cs
  1. using System;
  2. using System.Collections.Specialized;
  3. using BusinessServices;
  4.  
  5. namespace WebNHibernate
  6. {
  7.     public class BasePage : System.Web.UI.Page, IView
  8.     {
  9.  
  10.         private string _requestUrl;
  11.  
  12.         protected T RegisterView<T>() where T : Presenter
  13.         {
  14.             return PresentationManager.RegisterView<T>(typeof(T), this, new HttpSessionProvider());
  15.         }
  16.  
  17.         protected void SelfRegister(System.Web.UI.Page page)
  18.         {
  19.             if (page != null && page is IView)
  20.             {
  21.                 object[] attributes = page.GetType().GetCustomAttributes(typeof(PresenterTypeAttribute), true);
  22.  
  23.                 if (attributes != null && attributes.Length > 0)
  24.                 {
  25.                     foreach (Attribute viewAttribute in attributes)
  26.                     {
  27.                         if (viewAttribute is PresenterTypeAttribute)
  28.                         {
  29.                             PresentationManager.RegisterView((viewAttribute as PresenterTypeAttribute).PresenterType,
  30.                                 page as IView, new HttpSessionProvider());
  31.                             break;
  32.                         }
  33.                     }
  34.                 }
  35.             }
  36.         }
  37.  
  38.         public NameValueCollection RequestString
  39.         {
  40.             get { return Request.QueryString; }
  41.         }
  42.  
  43.         public string RequestUrl
  44.         {
  45.             get { return Request.RawUrl;  }
  46.             set { _requestUrl = value; }
  47.         }
  48.  
  49.         public bool IsPostback
  50.         {
  51.             get { return this.IsPostBack; }
  52.         }
  53.     }
  54. }

PersonPresenter

The PersonPresenter class now inherits the code that was commented out in the code behind file. It must also setup event listeners for events that will be raised from the web page. It is these event listeners that improve the testability of the solution, as now this functionality can be unit tested separate from any System.Web dependency. At this point the various presenters have a reference to NHibernate and work directly with the data access layer. The next iteration of the bootstrapper will refactor the presenter and place a data services layer between the presenter and the data access layer. The presenter will then no longer reference NHibernate.

PersonPresenter.cs (Part 1)
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using NHibernate;
  5. using NHibernateDAO;
  6. using NHibernateDAO.DAOImplementations;
  7. using DataServices.Person;
  8. using DomainModel.Person;
  9. using Infrastructure;
  10. using BusinessServices.Interfaces;
  11.  
  12. namespace BusinessServices.Presenters
  13. {
  14.     public class PersonPresenter : Presenter
  15.     {
  16.         private ISession m_session = null;
  17.  
  18.  
  19.         public PersonPresenter(IPersonView view)
  20.             : this(view, null)
  21.         { }
  22.  
  23.         public PersonPresenter(IPersonView view, IHttpSessionProvider httpSession)
  24.             : base(view, httpSession)
  25.         {
  26.             IPersonView _personView = null;
  27.             _personView = base.GetView<IPersonView>();
  28.             _personView.OnEditCommand += new GridViewBtnEvent(_view_OnEditCommand);
  29.             _personView.OnDeleteCommand += new GridViewBtnEvent(_view_OnDeleteCommand);
  30.             _personView.OnRefreshPersonGrid += new EmptyBtnEvent(_view_OnRefreshPersonGrid);
  31.             _personView.OnSaveEditPerson += new EmptyBtnEvent(_view_OnSaveEditPerson);
  32.             _personView.OnClearEditPerson += new EmptyBtnEvent(_view_OnClearEditPerson);
  33.             _personView.OnPageLoadNoPostback += new EmptyEvent(_personView_OnPageLoadNoPostback);
  34.         }
  35.  
  36.  
  37.         public void _personView_OnPageLoadNoPostback()
  38.         {
  39.             IPersonView _personView = base.GetView<IPersonView>();
  40.             IList<PersonDto> gvData = Get_PersonData();
  41.             _personView.Fill_gvPerson(gvData);
  42.         }
PersonPresenter.cs (Part 2)
  1. public void _view_OnEditCommand(Guid id)
  2. {
  3.     IPersonView _personView = base.GetView<IPersonView>();
  4.     m_session = SessionManager.SessionFactory.GetCurrentSession();
  5.  
  6.     PersonDAOImpl dao = new PersonDAOImpl(m_session);
  7.     DomainModel.Person.Person pers = dao.GetByID(id);
  8.  
  9.     _personView.txtPersonIdValue = pers.Id.ToString();
  10.     _personView.txtFirstNameValue = pers.FirstName;
  11.     _personView.txtLastNameValue = pers.LastName;
  12.     _personView.txtEmailValue = pers.Email;
  13.     _personView.txtUserIdValue = pers.UserID;
  14.  
  15.     pers = null;
  16.     dao = null;
  17. }
  18.  
  19. public void _view_OnDeleteCommand(Guid id)
  20. {
  21.     IPersonView _personView = base.GetView<IPersonView>();
  22.     m_session = SessionManager.SessionFactory.GetCurrentSession();
  23.  
  24.     PersonDAOImpl dao = new PersonDAOImpl(m_session);
  25.     using (var tx = m_session.BeginTransaction())
  26.     {
  27.         dao.Delete(id);
  28.         tx.Commit();
  29.     }
  30.  
  31.     dao = null;
  32.     _view_OnRefreshPersonGrid();
  33. }
  34.  
  35. public void _view_OnRefreshPersonGrid()
  36. {
  37.     IPersonView _personView = base.GetView<IPersonView>();
  38.     IList<PersonDto> gvData = Get_PersonData();
  39.     _personView.Fill_gvPerson(gvData);
  40. }
PersonPresenter.cs (Part 3)
  1. public void _view_OnSaveEditPerson()
  2. {
  3.     IPersonView _personView = base.GetView<IPersonView>();
  4.     m_session = SessionManager.SessionFactory.GetCurrentSession();
  5.  
  6.     Guid editId = new Guid();
  7.     Person editPers = new Person();
  8.  
  9.     if (!string.IsNullOrEmpty(_personView.txtPersonIdValue))
  10.         editId = new Guid(_personView.txtPersonIdValue);
  11.  
  12.     PersonDAOImpl dao = new PersonDAOImpl(m_session);
  13.     using (var tx = m_session.BeginTransaction())
  14.     {
  15.             if ((editId != null) && (!editId.Equals(System.Guid.Empty))) //was a bug here
  16.                 editPers = dao.GetByID(editId);
  17.             editPers.FirstName = _personView.txtFirstNameValue;
  18.             editPers.LastName = _personView.txtLastNameValue;
  19.             editPers.Email = _personView.txtEmailValue;
  20.             editPers.UserID = _personView.txtUserIdValue;
  21.  
  22.             editPers = dao.Save(editPers);
  23.             tx.Commit();
  24.     }
  25.  
  26.     editPers = null;
  27.     dao = null;
  28.     _view_OnRefreshPersonGrid();
  29.     _view_OnClearEditPerson();
  30. }
  31.  
  32. public void _view_OnClearEditPerson()
  33. {
  34.     IPersonView _personView = base.GetView<IPersonView>();
  35.  
  36.     _personView.txtPersonIdValue = null;
  37.     _personView.txtFirstNameValue = null;
  38.     _personView.txtLastNameValue = null;
  39.     _personView.txtEmailValue = null;
  40.     _personView.txtUserIdValue = null;
  41. }
PersonPresenter.cs (Part 4)
  1.         public IList<PersonDto> Get_PersonData()
  2.         {
  3.             IPersonView _personView = base.GetView<IPersonView>();
  4.             IList<PersonDto> retVal = null;
  5.  
  6.             m_session = SessionManager.SessionFactory.GetCurrentSession();
  7.  
  8.             ICriteria crit = m_session.CreateCriteria(typeof(Person));
  9.             PersonDAOImpl dao = new PersonDAOImpl(m_session);
  10.  
  11.             IList<Person> people = dao.GetByCriteria(crit);
  12.             retVal = (from person in people
  13.                       select new PersonDto
  14.                       {
  15.                           PersonID = person.Id,
  16.                           FirstName = person.FirstName,
  17.                           LastName = person.LastName,
  18.                           Email = person.Email,
  19.                           UserID = person.UserID
  20.                       }).ToList<PersonDto>();
  21.             crit = null;
  22.             dao = null;
  23.             people = null;
  24.  
  25.             return retVal;
  26.         }
  27.  
  28.         public IPersonView personView
  29.         {
  30.             get { return base.GetView<IPersonView>(); }
  31.         }
  32.  
  33.     }
  34. }

 

The interface for the PersonView web page has also had to be revised. Here the methods that are commented out have had the implementations moved from the web page to the presenter. One new event has been added for the presenter.

IPersonView.cs
  1. using System.Collections.Generic;
  2. using DataServices.Person;
  3.  
  4. namespace BusinessServices.Interfaces
  5. {
  6.  
  7.     public interface IPersonView : IView
  8.     {
  9.  
  10.         event GridViewBtnEvent OnEditCommand;
  11.         event GridViewBtnEvent OnDeleteCommand;
  12.         event EmptyBtnEvent OnRefreshPersonGrid;
  13.         event EmptyBtnEvent OnSaveEditPerson;
  14.         event EmptyBtnEvent OnClearEditPerson;
  15.         //the event below had to be added for the presenter
  16.         event EmptyEvent OnPageLoadNoPostback;
  17.  
  18.         //void _view_OnEditCommand(Guid id);
  19.         //void _view_OnDeleteCommand(Guid id);
  20.         //void _view_OnRefreshPersonGrid();
  21.         //void _view_OnSaveEditPerson();
  22.         //void _view_OnClearEditPerson();
  23.  
  24.         string txtPersonIdValue { get; set; }
  25.         string txtFirstNameValue { get; set; }
  26.         string txtLastNameValue { get; set; }
  27.         string txtEmailValue { get; set; }
  28.         string txtUserIdValue { get; set; }
  29.  
  30.         void Fill_gvPerson(IList<PersonDto> data);
  31.         //IList<PersonDto> Get_PersonData();
  32.  
  33.  
  34.     }
  35. }

Data Access Objects Improvements

The data access objects have been expanded to include support for NHibernate LINQ, which is now part of the core. Also support for selection of an unique object has been included, rather than always returning an IList. This means that there has been an update to the IRead.cs file as shown below.

 

IRead.cs
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using DomainModel;
  6. using NHibernate;
  7.  
  8. namespace NHibernateDAO
  9. {
  10.     public interface IRead<TEntity> where TEntity : Entity
  11.     {
  12.         TEntity GetByID(Guid ID);
  13.         IList<TEntity> GetByCriteria(ICriteria criteria);
  14.         TEntity GetUniqByCriteria(ICriteria criteria);
  15.         IList<TEntity> GetByQueryable(IQueryable<TEntity> queryable);
  16.         TEntity GetUniqByQueryable(IQueryable<TEntity> queryable);
  17.     }
  18. }

 

 

The implementation file for the data access objects has been revised to include the implementation details for LINQ and unique object support.

 

GenericDAOImpl.cs (Pt 1)
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using DomainModel;
  6. using NHibernate;
  7.  
  8. namespace NHibernateDAO
  9. {
  10.     public class GenericDAOImpl<TEntity> : IRead<TEntity>, ISave<TEntity> where TEntity : Entity
  11.     {
  12.         public GenericDAOImpl(ISession Session)
  13.         {
  14.             m_Session = Session;
  15.         }
  16.  
  17.         protected readonly ISession m_Session;
  18.  
  19.         public TEntity GetByID(Guid ID)
  20.         {
  21.             if (!m_Session.Transaction.IsActive)
  22.             {
  23.                 TEntity retval;
  24.                 using (var tx = m_Session.BeginTransaction())
  25.                 {
  26.                     retval = m_Session.Get<TEntity>(ID);
  27.                     tx.Commit();
  28.                     return retval;
  29.                 }
  30.             }
  31.             else
  32.             {
  33.                 return m_Session.Get<TEntity>(ID);
  34.             }
  35.         }

 

 

GenericDAOImpl.cs (Pt 2)
  1. public IList<TEntity> GetByCriteria(ICriteria criteria)
  2. {
  3.     if (!m_Session.Transaction.IsActive)
  4.     {
  5.         IList<TEntity> retval;
  6.         using (var tx = m_Session.BeginTransaction())
  7.         {
  8.             retval = criteria.List<TEntity>();
  9.             tx.Commit();
  10.             return retval;
  11.         }
  12.     }
  13.     else
  14.     {
  15.         return criteria.List<TEntity>();
  16.     }
  17. }
  18.  
  19. public TEntity GetUniqByCriteria(ICriteria criteria)
  20. {
  21.     if (!m_Session.Transaction.IsActive)
  22.     {
  23.         TEntity retval;
  24.         using (var tx = m_Session.BeginTransaction())
  25.         {
  26.             retval = criteria.UniqueResult<TEntity>();
  27.             tx.Commit();
  28.             return retval;
  29.         }
  30.     }
  31.     else
  32.     {
  33.         return criteria.UniqueResult<TEntity>();
  34.     }
  35. }

 

 

GenericDAOImpl.cs (Pt 3)
  1. public IList<TEntity> GetByQueryable(IQueryable<TEntity> queryable)
  2. {
  3.     if (!m_Session.Transaction.IsActive)
  4.     {
  5.         IList<TEntity> retval;
  6.         using (var tx = m_Session.BeginTransaction())
  7.         {
  8.             retval = queryable.ToList<TEntity>();
  9.             tx.Commit();
  10.             return retval;
  11.         }
  12.     }
  13.     else
  14.     {
  15.         return queryable.ToList<TEntity>();
  16.     }
  17. }
  18.  
  19. public TEntity GetUniqByQueryable(IQueryable<TEntity> queryable)
  20. {
  21.     if (!m_Session.Transaction.IsActive)
  22.     {
  23.         TEntity retval;
  24.         using (var tx = m_Session.BeginTransaction())
  25.         {
  26.             retval = queryable.Single<TEntity>();
  27.             tx.Commit();
  28.             return retval;
  29.         }
  30.     }
  31.     else
  32.     {
  33.         return queryable.Single<TEntity>();
  34.     }
  35. }

 

 

 

GenericDAOImpl.cs (Pt 4)
  1.         public TEntity Save(TEntity entity)
  2.         {
  3.             if (!m_Session.Transaction.IsActive)
  4.             {
  5.                 using (var tx = m_Session.BeginTransaction())
  6.                 {
  7.                     m_Session.SaveOrUpdate(entity);
  8.                     tx.Commit();
  9.                 }
  10.             }
  11.             else
  12.             {
  13.                 m_Session.SaveOrUpdate(entity);
  14.             }
  15.             return entity;
  16.         }
  17.  
  18.     }
  19. }

 

 

Unit Test

The unit testing capabilities of the solution have been expanded. It starts with a fake PersonView class in the unit test project that includes functionality similar to that in the web page, but implemented without any reference to System.Web

PersonView.cs (Part 1)
  1. using System;
  2. using System.Collections.Generic;
  3. using BusinessServices;
  4. using BusinessServices.Interfaces;
  5. using BusinessServices.Presenters;
  6. using DataServices.Person;
  7.  
  8. namespace BootstrapperUnitTests.Views
  9. {
  10.     [PresenterType(typeof(PersonPresenter))]
  11.     public class PersonView : BaseView, IPersonView
  12.     {
  13.         private bool blnRegistered = false;
  14.  
  15.         private string _txtPersonID;
  16.         private string _txtFirstName;
  17.         private string _txtLastName;
  18.         private string _txtEmail;
  19.         private string _txtUserID;
  20.         private static bool postBack;
  21.  
  22.         private IList<PersonDto> _gvPerson;
  23.  
  24.         public event GridViewBtnEvent OnEditCommand;
  25.         public event GridViewBtnEvent OnDeleteCommand;
  26.         public event EmptyBtnEvent OnRefreshPersonGrid;
  27.         public event EmptyBtnEvent OnSaveEditPerson;
  28.         public event EmptyBtnEvent OnClearEditPerson;
  29.         public event EmptyEvent OnPageLoadNoPostback;
  30.  
  31.         public PersonView()
  32.         {
  33.             postBack = false;
  34.             base.SelfRegister(this);
  35.             blnRegistered = true;
  36.         }
  37.  
  38.         /// <summary>
  39.         /// This is used by the test subsystem to avoid the self-registry action and allow normal
  40.         /// object creation.
  41.         /// </summary>
  42.         /// <param name="noRegister"></param>
  43.         public PersonView(bool noRegister)
  44.         {
  45.             blnRegistered = false;
  46.             postBack = false;
  47.         }
PersonView.cs (Part 2)
  1. public void Fill_gvPerson(IList<PersonDto> data)
  2. {
  3.     _gvPerson = data;
  4. }
  5.  
  6. protected internal IList<PersonDto> GvPerson
  7. {
  8.     get { return _gvPerson; }
  9. }
  10.  
  11. public void FireEvent_OnEditCommand(Guid id)
  12. {
  13.     OnEditCommand(id);
  14. }
  15.  
  16. public void FireEvent_OnDeleteCommand(Guid id)
  17. {
  18.     OnDeleteCommand(id);
  19. }
  20.  
  21. public void FireEvent_OnRefreshPersonGrid()
  22. {
  23.     OnRefreshPersonGrid();
  24. }
  25.  
  26. public void FireEvent_OnSaveEditPerson()
  27. {
  28.     if (_txtUserID != null)
  29.     {
  30.         OnSaveEditPerson();
  31.     }
  32. }
  33.  
  34. public void FireEvent_OnClearEditPerson()
  35. {
  36.     OnClearEditPerson();
  37. }
  38.  
  39. public void FireEvent_OnPageLoadNoPostback()
  40. {
  41.     OnPageLoadNoPostback();
  42. }

 

PersonView.cs (Part 3)
  1.         public string txtPersonIdValue
  2.         {
  3.             get { return _txtPersonID; }
  4.             set { _txtPersonID = value; }
  5.         }
  6.  
  7.         public string txtFirstNameValue
  8.         {
  9.             get { return _txtFirstName; }
  10.             set { _txtFirstName = value; }
  11.         }
  12.  
  13.         public string txtLastNameValue
  14.         {
  15.             get { return _txtLastName; }
  16.             set { _txtLastName = value; }
  17.         }
  18.  
  19.         public string txtEmailValue
  20.         {
  21.             get { return _txtEmail; }
  22.             set { _txtEmail = value; }
  23.         }
  24.  
  25.         public string txtUserIdValue
  26.         {
  27.             get { return _txtUserID; }
  28.             set { _txtUserID = value; }
  29.         }
  30.  
  31.         bool IView.IsPostback
  32.         {
  33.             get
  34.             {
  35.                 if (!postBack)
  36.                 {
  37.                     postBack = true;
  38.                     return false;
  39.                 }
  40.                 else
  41.                     return true;
  42.             }
  43.         }
  44.     }
  45. }

 

BasePage.cs must also be copied to the unit test project, and it also no longer references System.Web. It is renamed to BaseView.cs in the actual solution. You will note that the property IsPostBack throws a NotImplementedException, but it could be set to a read/write property and provide values through an external property setter in the tests.

BaseView.cs
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.Specialized;
  4. using System.Linq;
  5. using System.Text;
  6. using BusinessServices;
  7.  
  8. namespace BootstrapperUnitTests
  9. {
  10.     public class BaseView : IView
  11.     {
  12.         private string _requestUrl;
  13.         private NameValueCollection _queryString = new NameValueCollection();
  14.         
  15.  
  16.         protected T RegisterView<T>() where T : Presenter
  17.         {
  18.             return PresentationManager.RegisterView<T>(typeof(T), this, null);
  19.         }
  20.  
  21.         protected void SelfRegister(IView page)
  22.         {
  23.             if (page != null && page is IView)
  24.             {
  25.                 object[] attributes = page.GetType().GetCustomAttributes(typeof(PresenterTypeAttribute), true);
  26.  
  27.                 if (attributes != null && attributes.Length > 0)
  28.                 {
  29.                     foreach (Attribute viewAttribute in attributes)
  30.                     {
  31.                         if (viewAttribute is PresenterTypeAttribute)
  32.                         {
  33.                             PresentationManager.RegisterView((viewAttribute as PresenterTypeAttribute).PresenterType,
  34.                                 page as IView, null);
  35.                             break;
  36.                         }
  37.                     }
  38.                 }
  39.             }
  40.         }
  41.  
  42.         public NameValueCollection RequestString
  43.         {
  44.             get { return _queryString; }
  45.         }
  46.  
  47.         public string RequestUrl
  48.         {
  49.             get { return _requestUrl; }
  50.             set { _requestUrl = value; }
  51.         }
  52.  
  53.         public bool IsPostback
  54.         {
  55.             get { throw new NotImplementedException(); }
  56.         }
  57.     }
  58. }

 

 

The tests themselves have been expanded and now show a considerably increased code coverage. In doing so the tests are now a combination of unit tests and integration tests, but I would argue that this is desirable as it increases the overall reliability of the solution, which is the purpose of automated tests.

PersonPresenterTests.cs (Pt 1)
  1. using System;
  2. using System.Collections.Generic;
  3. using NUnit.Framework;
  4. using DomainModel.Person;
  5. using NHibernate;
  6. using NHibernate.Context;
  7. using NHibernateDAO;
  8. using NHibernateDAO.DAOImplementations;
  9. using BootstrapperUnitTests.Views;
  10. using BootstrapperUnitTests.TestData;
  11. using BusinessServices.Interfaces;
  12. using BusinessServices.Presenters;
  13. using DataServices.Person;
  14.  
  15. namespace BootstrapperUnitTests.PresenterTests
  16. {
  17.     [TestFixture]
  18.     public class PersonPresenterTests
  19.     {
  20.         private ISession m_session;
  21.  
  22.         [TestFixtureSetUp]
  23.         public void TestFixtureSetup()
  24.         {
  25.             var session = SessionManager.SessionFactory.OpenSession();
  26.             CallSessionContext.Bind(session);
  27.         }
  28.  
  29.         [TestFixtureTearDown]
  30.         public void TestFixtureTeardown()
  31.         {
  32.             PersonTestData ptd = new PersonTestData();
  33.             ptd.RemoveAllPersonEntries();
  34.  
  35.             var session = CallSessionContext.Unbind(SessionManager.SessionFactory);
  36.             if (session != null)
  37.             {
  38.                 if (session.Transaction != null && session.Transaction.IsActive)
  39.                 {
  40.                     session.Transaction.Rollback();
  41.                 }
  42.                 else
  43.                     session.Flush();
  44.  
  45.                 session.Close();
  46.             }
  47.  
  48.             session.Dispose();
  49.         }
PersonPresenterTests.cs (Pt 2)
  1. [Test]
  2. public void View_OnEditCommandTest()
  3. {
  4.     PersonTestData ptd = new PersonTestData();
  5.     ptd.CreatePersonEntries(1);
  6.  
  7.     m_session = SessionManager.SessionFactory.GetCurrentSession();
  8.     ICriteria crit = m_session.CreateCriteria(typeof(Person));
  9.     PersonDAOImpl daoPerson = new PersonDAOImpl(m_session);
  10.  
  11.     IList<Person> people;
  12.  
  13.     using (var tx = m_session.BeginTransaction())
  14.     {
  15.         people = daoPerson.GetByCriteria(crit);
  16.         tx.Commit();
  17.         Assert.GreaterOrEqual(people.Count, 1);
  18.     }
  19.  
  20.     PersonPresenter _pp =new PersonPresenter(new PersonView(false));
  21.  
  22.     daoPerson = null;
  23.     m_session = null;
  24.  
  25.     _pp._view_OnEditCommand(people[0].Id);
  26.     IPersonView _pv = _pp.personView;
  27.     Assert.IsTrue(new Guid(_pv.txtPersonIdValue).Equals(people[0].Id));
  28.     Assert.IsTrue(_pv.txtUserIdValue.Equals(people[0].UserID));
  29.  
  30.     ptd = null;
  31.     _pv = null;
  32.     _pp = null;
  33. }
PersonPresenterTests.cs (Pt 3)
  1. [Test]
  2. public void FireEvent_OnEditCommandTest()
  3. {
  4.     PersonTestData ptd = new PersonTestData();
  5.     ptd.CreatePersonEntries(1);
  6.  
  7.     m_session = SessionManager.SessionFactory.GetCurrentSession();
  8.     ICriteria crit = m_session.CreateCriteria(typeof(Person));
  9.     PersonDAOImpl daoPerson = new PersonDAOImpl(m_session);
  10.  
  11.     IList<Person> people;
  12.  
  13.     using (var tx = m_session.BeginTransaction())
  14.     {
  15.         people = daoPerson.GetByCriteria(crit);
  16.         tx.Commit();
  17.         Assert.GreaterOrEqual(people.Count, 1);
  18.     }
  19.  
  20.     IPersonView _pv = new PersonView();
  21.     PersonView _pvc = _pv as PersonView;
  22.  
  23.     daoPerson = null;
  24.     m_session = null;
  25.  
  26.     _pvc.FireEvent_OnEditCommand(people[0].Id);
  27.     Assert.IsTrue(new Guid(_pv.txtPersonIdValue).Equals(people[0].Id));
  28.     Assert.IsTrue(_pv.txtUserIdValue.Equals(people[0].UserID));
  29.  
  30.     ptd = null;
  31.     _pv = null;
  32.     _pvc = null;
  33. }
PersonPresenterTests.cs (Pt 4)
  1. [Test]
  2. public void View_OnDeleteCommandTest()
  3. {
  4.     PersonTestData ptd = new PersonTestData();
  5.     ptd.RemoveAllPersonEntries();
  6.     ptd.CreatePersonEntries(1);
  7.  
  8.     m_session = SessionManager.SessionFactory.GetCurrentSession();
  9.     ICriteria crit = m_session.CreateCriteria(typeof(Person));
  10.     PersonDAOImpl daoPerson = new PersonDAOImpl(m_session);
  11.  
  12.     IList<Person> people;
  13.  
  14.     using (var tx = m_session.BeginTransaction())
  15.     {
  16.         people = daoPerson.GetByCriteria(crit);
  17.         tx.Commit();
  18.         Assert.GreaterOrEqual(people.Count, 1);
  19.     }
  20.  
  21.     PersonPresenter _pp = new PersonPresenter(new PersonView(false));
  22.     IPersonView _pv = _pp.personView;
  23.  
  24.     daoPerson = null;
  25.     m_session = null;
  26.  
  27.     _pp._view_OnDeleteCommand(people[0].Id);
  28.  
  29.     m_session = SessionManager.SessionFactory.GetCurrentSession();
  30.     daoPerson = new PersonDAOImpl(m_session);
  31.  
  32.     using (var tx = m_session.BeginTransaction())
  33.     {
  34.         people = daoPerson.GetByCriteria(crit);
  35.         tx.Commit();
  36.         Assert.AreEqual(people.Count, 0);
  37.     }
  38.  
  39.     ptd = null;
  40.     _pv = null;
  41.     _pp = null;
  42. }
PersonPresenterTests.cs (Pt 5)
  1. [Test]
  2. public void FireEvent_OnDeleteCommandTest()
  3. {
  4.     PersonTestData ptd = new PersonTestData();
  5.     ptd.RemoveAllPersonEntries();
  6.     ptd.CreatePersonEntries(1);
  7.  
  8.     m_session = SessionManager.SessionFactory.GetCurrentSession();
  9.     ICriteria crit = m_session.CreateCriteria(typeof(Person));
  10.     PersonDAOImpl daoPerson = new PersonDAOImpl(m_session);
  11.  
  12.     IList<Person> people;
  13.  
  14.     using (var tx = m_session.BeginTransaction())
  15.     {
  16.         people = daoPerson.GetByCriteria(crit);
  17.         tx.Commit();
  18.         Assert.GreaterOrEqual(people.Count, 1);
  19.     }
  20.  
  21.     IPersonView _pv = new PersonView();
  22.     PersonView _pvc = _pv as PersonView;
  23.  
  24.     daoPerson = null;
  25.     m_session = null;
  26.  
  27.     _pvc.FireEvent_OnDeleteCommand(people[0].Id);
  28.  
  29.     m_session = SessionManager.SessionFactory.GetCurrentSession();
  30.     daoPerson = new PersonDAOImpl(m_session);
  31.  
  32.     using (var tx = m_session.BeginTransaction())
  33.     {
  34.         people = daoPerson.GetByCriteria(crit);
  35.         tx.Commit();
  36.         Assert.AreEqual(people.Count, 0);
  37.     }
  38.  
  39.     ptd = null;
  40.     _pv = null;
  41.     _pvc = null;
  42. }
PersonPresenterTests.cs (Pt 6)
  1.         [Test]
  2.         public void View_OnClearEditPerson()
  3.         {
  4.             PersonPresenter _pp = new PersonPresenter(new PersonView(false));
  5.             IPersonView _pv = _pp.personView;
  6.  
  7.             _pv.txtFirstNameValue = "testData";
  8.  
  9.             _pp._view_OnClearEditPerson();
  10.             Assert.IsNullOrEmpty(_pv.txtFirstNameValue);
  11.  
  12.             _pv = null;
  13.             _pp = null;
  14.         }
  15.  
  16.         [Test]
  17.         public void FireEvent_OnClearEditPerson()
  18.         {
  19.             IPersonView _pv = new PersonView();
  20.             PersonView _pvc = _pv as PersonView;
  21.  
  22.             _pv.txtFirstNameValue = "testData";
  23.  
  24.             _pvc.FireEvent_OnClearEditPerson();
  25.             Assert.IsNullOrEmpty(_pv.txtFirstNameValue);
  26.  
  27.             _pv = null;
  28.             _pvc = null;
  29.         }
  30.  
  31.         [Test]
  32.         public void Get_PersonDataTest()
  33.         {
  34.             PersonTestData ptd = new PersonTestData();
  35.             ptd.CreatePersonEntries(3);
  36.  
  37.             m_session = SessionManager.SessionFactory.GetCurrentSession();
  38.             ICriteria crit = m_session.CreateCriteria(typeof(Person));
  39.             PersonDAOImpl daoPerson = new PersonDAOImpl(m_session);
  40.  
  41.             IList<Person> people;
  42.  
  43.             using (var tx = m_session.BeginTransaction())
  44.             {
  45.                 people = daoPerson.GetByCriteria(crit);
  46.                 tx.Commit();
  47.                 Assert.GreaterOrEqual(people.Count, 1);
  48.             }
  49.  
  50.             PersonPresenter _pp = new PersonPresenter(new PersonView(false));
  51.             Assert.IsInstanceOf<PersonPresenter>(_pp);
  52.  
  53.             daoPerson = null;
  54.             m_session = null;
  55.  
  56.             IList<PersonDto> pers = _pp.Get_PersonData();
  57.             Assert.GreaterOrEqual(pers.Count, 3);
  58.  
  59.             ptd = null;
  60.  
  61.             _pp = null;
  62.         }
PersonPresenterTests.cs (Pt 7)
  1. [Test]
  2. public void FireEvent_OnPageLoadNoPostbackTest()
  3. {
  4.     PersonTestData ptd = new PersonTestData();
  5.     ptd.CreatePersonEntries(3);
  6.  
  7.     m_session = SessionManager.SessionFactory.GetCurrentSession();
  8.     ICriteria crit = m_session.CreateCriteria(typeof(Person));
  9.     PersonDAOImpl daoPerson = new PersonDAOImpl(m_session);
  10.  
  11.     IList<Person> people;
  12.  
  13.     using (var tx = m_session.BeginTransaction())
  14.     {
  15.         people = daoPerson.GetByCriteria(crit);
  16.         tx.Commit();
  17.         Assert.GreaterOrEqual(people.Count, 1);
  18.     }
  19.  
  20.     IPersonView _pv = new PersonView();
  21.     PersonView _pvc = _pv as PersonView;
  22.  
  23.     people = null;
  24.     daoPerson = null;
  25.     m_session = null;
  26.  
  27.     _pvc.FireEvent_OnPageLoadNoPostback();
  28.     Assert.GreaterOrEqual(_pvc.GvPerson.Count, 3);
  29.  
  30.     ptd = null;
  31.     _pv = null;
  32.     _pvc = null;
  33. }
PersonPresenterTests.cs (Pt 8)
  1. [Test]
  2. public void View_OnRefreshPersonGridTest()
  3. {
  4.     PersonTestData ptd = new PersonTestData();
  5.     ptd.CreatePersonEntries(3);
  6.  
  7.     m_session = SessionManager.SessionFactory.GetCurrentSession();
  8.     ICriteria crit = m_session.CreateCriteria(typeof(Person));
  9.     PersonDAOImpl daoPerson = new PersonDAOImpl(m_session);
  10.  
  11.     IList<Person> people;
  12.  
  13.     using (var tx = m_session.BeginTransaction())
  14.     {
  15.         people = daoPerson.GetByCriteria(crit);
  16.         tx.Commit();
  17.         Assert.GreaterOrEqual(people.Count, 1);
  18.     }
  19.  
  20.     PersonPresenter _pp = new PersonPresenter(new PersonView(false));
  21.     IPersonView _pv = _pp.personView;
  22.     PersonView _pvc = _pv as PersonView;
  23.  
  24.     people = null;
  25.     daoPerson = null;
  26.     m_session = null;
  27.  
  28.     _pvc.FireEvent_OnRefreshPersonGrid();
  29.     Assert.GreaterOrEqual(_pvc.GvPerson.Count, 3);
  30.  
  31.     ptd = null;
  32.     _pp = null;
  33.     _pv = null;
  34.     _pvc = null;
  35. }
PersonPresenter.cs (Pt 9)
  1. [Test]
  2. public void FireEvent_OnRefreshPersonGridTest()
  3. {
  4.     PersonTestData ptd = new PersonTestData();
  5.     ptd.CreatePersonEntries(3);
  6.  
  7.     m_session = SessionManager.SessionFactory.GetCurrentSession();
  8.     ICriteria crit = m_session.CreateCriteria(typeof(Person));
  9.     PersonDAOImpl daoPerson = new PersonDAOImpl(m_session);
  10.  
  11.     IList<Person> people;
  12.  
  13.     using (var tx = m_session.BeginTransaction())
  14.     {
  15.         people = daoPerson.GetByCriteria(crit);
  16.         tx.Commit();
  17.         Assert.GreaterOrEqual(people.Count, 1);
  18.     }
  19.  
  20.     IPersonView _pv = new PersonView();
  21.     PersonView _pvc = _pv as PersonView;
  22.  
  23.     people = null;
  24.     daoPerson = null;
  25.     m_session = null;
  26.  
  27.     _pvc.FireEvent_OnRefreshPersonGrid();
  28.     Assert.GreaterOrEqual(_pvc.GvPerson.Count, 3);
  29.  
  30.     ptd = null;
  31.  
  32.     _pv = null;
  33.     _pvc = null;
  34. }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

PersonPresenterTests.cs (Pt10)
  1. [Test]
  2. public void View_OnSaveEditPersonNewTest()
  3. {
  4.     PersonTestData ptd = new PersonTestData();
  5.     ptd.RemoveAllPersonEntries();
  6.  
  7.     PersonPresenter _pp = new PersonPresenter(new PersonView(false));
  8.     IPersonView _pv = _pp.personView;
  9.  
  10.     _pv.txtPersonIdValue = "";
  11.     _pv.txtFirstNameValue = "Mary";
  12.     _pv.txtLastNameValue = "Johnston";
  13.     _pv.txtEmailValue = "some@email";
  14.     _pv.txtUserIdValue = "mj1";
  15.  
  16.     _pp._view_OnSaveEditPerson();
  17.  
  18.     _pv = null;
  19.     _pp = null;
  20.  
  21.     m_session = SessionManager.SessionFactory.GetCurrentSession();
  22.     ICriteria crit = m_session.CreateCriteria(typeof(Person));
  23.     PersonDAOImpl daoPerson = new PersonDAOImpl(m_session);
  24.  
  25.     IList<Person> people;
  26.  
  27.     using (var tx = m_session.BeginTransaction())
  28.     {
  29.         people = daoPerson.GetByCriteria(crit);
  30.         tx.Commit();
  31.         Assert.GreaterOrEqual(people.Count, 1);
  32.     }
  33.  
  34.     people = null;
  35.     daoPerson = null;
  36.     m_session = null;
  37.  
  38.     ptd = null;
  39. }
PersonPresneterTests.cs (Pt11)
  1. [Test]
  2. public void FireEvent_OnSaveEditPersonNewTest()
  3. {
  4.     PersonTestData ptd = new PersonTestData();
  5.     ptd.RemoveAllPersonEntries();
  6.  
  7.     IPersonView _pv = new PersonView();
  8.  
  9.     _pv.txtPersonIdValue = "";
  10.     _pv.txtFirstNameValue = "Mary";
  11.     _pv.txtLastNameValue = "Johnston";
  12.     _pv.txtEmailValue = "some@email";
  13.     _pv.txtUserIdValue = "mj1";
  14.  
  15.     PersonView _pvc = _pv as PersonView;
  16.     _pvc.FireEvent_OnSaveEditPerson();
  17.  
  18.     _pv = null;
  19.     _pvc = null;
  20.  
  21.     m_session = SessionManager.SessionFactory.GetCurrentSession();
  22.     ICriteria crit = m_session.CreateCriteria(typeof(Person));
  23.     PersonDAOImpl daoPerson = new PersonDAOImpl(m_session);
  24.  
  25.     IList<Person> people;
  26.  
  27.     using (var tx = m_session.BeginTransaction())
  28.     {
  29.         people = daoPerson.GetByCriteria(crit);
  30.         tx.Commit();
  31.         Assert.GreaterOrEqual(people.Count, 1);
  32.     }
  33.  
  34.     people = null;
  35.     daoPerson = null;
  36.     m_session = null;
  37.  
  38.     ptd = null;
  39. }
PersonPresenterTests.cs (Pt12)
  1. [Test]
  2. public void View_OnSaveEditPersonExistingTest()
  3. {
  4.     PersonTestData ptd = new PersonTestData();
  5.     ptd.RemoveAllPersonEntries();
  6.     ptd.CreatePersonEntries(1);
  7.  
  8.     m_session = SessionManager.SessionFactory.GetCurrentSession();
  9.     ICriteria crit = m_session.CreateCriteria(typeof(Person));
  10.     PersonDAOImpl daoPerson = new PersonDAOImpl(m_session);
  11.  
  12.     IList<Person> people;
  13.  
  14.     using (var tx = m_session.BeginTransaction())
  15.     {
  16.         people = daoPerson.GetByCriteria(crit);
  17.         tx.Commit();
  18.         Assert.GreaterOrEqual(people.Count, 1);
  19.     }
  20.  
  21.     PersonPresenter _pp = new PersonPresenter(new PersonView(false));
  22.     IPersonView _pv = _pp.personView;
  23.  
  24.     _pv.txtPersonIdValue = people[0].Id.ToString();
  25.     _pv.txtFirstNameValue = people[0].FirstName;
  26.     _pv.txtLastNameValue = people[0].LastName;
  27.     _pv.txtEmailValue = people[0].Email;
  28.     _pv.txtUserIdValue = "differentUser";
  29.  
  30.     _pp._view_OnSaveEditPerson();
  31.  
  32.     _pv = null;
  33.     _pp = null;
  34.  
  35.     m_session = SessionManager.SessionFactory.GetCurrentSession();
  36.     crit = m_session.CreateCriteria(typeof(Person));
  37.     daoPerson = new PersonDAOImpl(m_session);
  38.  
  39.     using (var tx = m_session.BeginTransaction())
  40.     {
  41.         people = daoPerson.GetByCriteria(crit);
  42.         tx.Commit();
  43.         Assert.GreaterOrEqual(people.Count, 1);
  44.     }
  45.  
  46.     people = null;
  47.     daoPerson = null;
  48.     m_session = null;
  49.  
  50.     ptd = null;
  51. }
PersonPresenterTests.cs (Pt13)
  1.         [Test]
  2.         public void FireEvent_OnSaveEditPersonExistingTest()
  3.         {
  4.             PersonTestData ptd = new PersonTestData();
  5.             ptd.RemoveAllPersonEntries();
  6.             ptd.CreatePersonEntries(1);
  7.  
  8.             m_session = SessionManager.SessionFactory.GetCurrentSession();
  9.             ICriteria crit = m_session.CreateCriteria(typeof(Person));
  10.             PersonDAOImpl daoPerson = new PersonDAOImpl(m_session);
  11.  
  12.             IList<Person> people;
  13.  
  14.             using (var tx = m_session.BeginTransaction())
  15.             {
  16.                 people = daoPerson.GetByCriteria(crit);
  17.                 tx.Commit();
  18.                 Assert.GreaterOrEqual(people.Count, 1);
  19.             }
  20.  
  21.             IPersonView _pv = new PersonView();
  22.  
  23.             _pv.txtPersonIdValue = people[0].Id.ToString();
  24.             _pv.txtFirstNameValue = people[0].FirstName;
  25.             _pv.txtLastNameValue = people[0].LastName;
  26.             _pv.txtEmailValue = people[0].Email;
  27.             _pv.txtUserIdValue = "differentUser";
  28.  
  29.             PersonView _pvc = _pv as PersonView;
  30.             _pvc.FireEvent_OnSaveEditPerson();
  31.  
  32.             _pv = null;
  33.             _pvc = null;
  34.  
  35.             m_session = SessionManager.SessionFactory.GetCurrentSession();
  36.             crit = m_session.CreateCriteria(typeof(Person));
  37.             daoPerson = new PersonDAOImpl(m_session);
  38.  
  39.             using (var tx = m_session.BeginTransaction())
  40.             {
  41.                 people = daoPerson.GetByCriteria(crit);
  42.                 tx.Commit();
  43.                 Assert.GreaterOrEqual(people.Count, 1);
  44.             }
  45.  
  46.             people = null;
  47.             daoPerson = null;
  48.             m_session = null;
  49.  
  50.             ptd = null;
  51.         }
  52.  
  53.     }
  54. }

Unit tests have also been included for an unique object and also for the added NHibernate LINQ capabilities

PersonDAOImplTest.cs (Pt 1)
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using DomainModel.Person;
  6. using NHibernateDAO;
  7. using NHibernateDAO.DAOImplementations;
  8. using NUnit.Framework;
  9. using NHibernate;
  10. using NHibernate.Context;
  11. using NHibernate.Linq;
  12. using BootstrapperUnitTests.TestData;
  13.  
  14. namespace BootstrapperUnitTests
  15. {
  16.     [TestFixture]
  17.     public class PersonDAOImplTests
  18.     {
  19.  
  20.         private ISession m_session;
  21.  
  22.         [TestFixtureSetUp]
  23.         public void TestFixtureSetup()
  24.         {
  25.             var session = SessionManager.SessionFactory.OpenSession();
  26.             CallSessionContext.Bind(session);
  27.         }
  28.  
  29.         [TestFixtureTearDown]
  30.         public void TestFixtureTeardown()
  31.         {
  32.             PersonTestData ptd = new PersonTestData();
  33.             ptd.RemoveAllPersonEntries();
  34.  
  35.             var session = CallSessionContext.Unbind(SessionManager.SessionFactory);
  36.             if (session != null)
  37.             {
  38.                 if (session.Transaction != null && session.Transaction.IsActive)
  39.                 {
  40.                     session.Transaction.Rollback();
  41.                 }
  42.                 else
  43.                     session.Flush();
  44.  
  45.                 session.Close();
  46.             }
  47.  
  48.             session.Dispose();
  49.         }

 

 

PersonDAOImplTests.cs (Pt 2)
  1. [Test]
  2. public void PersonSaveTestWithTx()
  3. {
  4.     m_session = SessionManager.SessionFactory.GetCurrentSession();
  5.     Person _person = new Person();
  6.     _person.FirstName = "John";
  7.     _person.LastName = "Davidson";
  8.     _person.Email = "jwdavidson@gmail.com";
  9.     _person.UserID = "jwd";
  10.     PersonDAOImpl daoPerson = new PersonDAOImpl(m_session);
  11.     
  12.     using (var tx = m_session.BeginTransaction())
  13.     {
  14.         Person newPerson = daoPerson.Save(_person);
  15.         tx.Commit();
  16.         Assert.AreEqual(_person, newPerson);
  17.     }
  18.  
  19.     _person = null;
  20.     daoPerson = null;
  21.     m_session = null;
  22. }
  23.  
  24. [Test]
  25. public void PersonCriteriaQueryTestWithTx()
  26. {
  27.     PersonTestData ptd = new PersonTestData();
  28.     ptd.CreatePersonEntries(3);
  29.  
  30.     m_session = SessionManager.SessionFactory.GetCurrentSession();
  31.     ICriteria crit = m_session.CreateCriteria(typeof(Person));
  32.     PersonDAOImpl daoPerson = new PersonDAOImpl(m_session);
  33.  
  34.     using (var tx = m_session.BeginTransaction())
  35.     {
  36.         IList<Person> people = daoPerson.GetByCriteria(crit);
  37.         tx.Commit();
  38.         Assert.GreaterOrEqual(people.Count, 3);
  39.     }
  40.  
  41.     daoPerson = null;
  42.     m_session = null;
  43.  
  44.     ptd.RemoveAllPersonEntries();
  45.     ptd = null;
  46. }
PersonDAOImplTest.cs (Pt 3)
  1. [Test]
  2. public void PersonDeleteTestWithTx()
  3. {
  4.     m_session = SessionManager.SessionFactory.GetCurrentSession();
  5.     m_session.FlushMode = FlushMode.Commit;
  6.     Person _person = new Person();
  7.     _person.FirstName = "John";
  8.     _person.LastName = "Davidson";
  9.     _person.Email = "jwdavidson@gmail.com";
  10.     _person.UserID = "jwd";
  11.     PersonDAOImpl daoPerson = new PersonDAOImpl(m_session);
  12.  
  13.     Person newPerson;
  14.     using (var tx = m_session.BeginTransaction())
  15.     {
  16.         newPerson = daoPerson.Save(_person);
  17.         tx.Commit();
  18.         Assert.AreEqual(_person, newPerson);
  19.         Console.WriteLine("Person ID: {0}", newPerson.Id);
  20.     }
  21.  
  22.     ICriteria crit = m_session.CreateCriteria(typeof(Person));
  23.     
  24.     Int32 pers = 0;
  25.     using (var tx = m_session.BeginTransaction())
  26.     {
  27.         IList<Person> people = daoPerson.GetByCriteria(crit);
  28.         tx.Commit();
  29.         Assert.Greater(people.Count, 0);
  30.         pers = people.Count;
  31.         Console.WriteLine("Count After Add: {0}", pers);
  32.     }
  33.  
  34.     using (var tx = m_session.BeginTransaction())
  35.     {
  36.         daoPerson.Delete(newPerson);
  37.         tx.Commit();
  38.         newPerson = null;
  39.     }
  40.  
  41.     using (var tx = m_session.BeginTransaction())
  42.     {
  43.         IList<Person> people = daoPerson.GetByCriteria(crit);
  44.         tx.Commit();
  45.         Console.WriteLine("Count after Delete: {0}", people.Count);
  46.  
  47.         Assert.IsTrue(pers.Equals(people.Count + 1));
  48.     }
  49.  
  50.     _person = null;
  51.     daoPerson = null;
  52.     m_session = null;
  53. }
PersonDAOImplTests.cs (Pt 4)
  1. [Test]
  2. public void PersonSaveTestWithoutTx()
  3. {
  4.     m_session = SessionManager.SessionFactory.GetCurrentSession();
  5.     Person _person = new Person();
  6.     _person.FirstName = "John";
  7.     _person.LastName = "Davidson";
  8.     _person.Email = "jwdavidson@gmail.com";
  9.     _person.UserID = "jwd";
  10.     PersonDAOImpl daoPerson = new PersonDAOImpl(m_session);
  11.     Person newPerson = daoPerson.Save(_person);
  12.  
  13.     Assert.AreEqual(_person, newPerson);
  14.     _person = null;
  15.     newPerson = null;
  16.     daoPerson = null;
  17.     m_session = null;
  18. }
  19.  
  20. [Test]
  21. public void PersonCriteriaQueryTestWithoutTx()
  22. {
  23.     PersonTestData ptd = new PersonTestData();
  24.     ptd.CreatePersonEntries(3);
  25.  
  26.     m_session = SessionManager.SessionFactory.GetCurrentSession();
  27.     ICriteria crit = m_session.CreateCriteria(typeof(Person));
  28.     PersonDAOImpl daoPerson = new PersonDAOImpl(m_session);
  29.     IList<Person> people = daoPerson.GetByCriteria(crit);
  30.  
  31.     Assert.GreaterOrEqual(people.Count, 3);
  32.     people = null;
  33.     daoPerson = null;
  34.     m_session = null;
  35.  
  36.     ptd.RemoveAllPersonEntries();
  37.     ptd = null;
  38. }
PersonDAOImplTest.cs (Pt 5)
  1. [Test]
  2. public void PersonLinqQueryTestWithTx()
  3. {
  4.     PersonTestData ptd = new PersonTestData();
  5.     ptd.CreatePersonEntries(3);
  6.  
  7.     m_session = SessionManager.SessionFactory.GetCurrentSession();
  8.     IQueryable<Person> qry = from p in m_session.Query<Person>() select p;
  9.     PersonDAOImpl daoPerson = new PersonDAOImpl(m_session);
  10.  
  11.     using (ITransaction tx = m_session.BeginTransaction())
  12.     {
  13.         IList<Person> people = daoPerson.GetByQueryable(qry);
  14.         tx.Commit();
  15.         Assert.GreaterOrEqual(people.Count, 3);
  16.     }
  17.  
  18.     daoPerson = null;
  19.     m_session = null;
  20.  
  21.     ptd.RemoveAllPersonEntries();
  22.     ptd = null;
  23. }
  24.  
  25. [Test]
  26. public void PersonLinqQueryWhereTestWithTx()
  27. {
  28.     PersonTestData ptd = new PersonTestData();
  29.     ptd.CreatePersonEntries(3);
  30.  
  31.     string userid = "jwd2";
  32.  
  33.     m_session = SessionManager.SessionFactory.GetCurrentSession();
  34.     IQueryable<Person> qry = from p in m_session.Query<Person>() where p.UserID == userid select p;
  35.     PersonDAOImpl daoPerson = new PersonDAOImpl(m_session);
  36.  
  37.     using (ITransaction tx = m_session.BeginTransaction())
  38.     {
  39.         IList<Person> people = daoPerson.GetByQueryable(qry);
  40.         tx.Commit();
  41.         Assert.GreaterOrEqual(people.Count, 1);
  42.     }
  43.  
  44.     daoPerson = null;
  45.     m_session = null;
  46.  
  47.     ptd.RemoveAllPersonEntries();
  48.     ptd = null;
  49. }
PersonDAOImplTests.cs (Pt 6)
  1. [Test]
  2. public void PersonLinqQueryTestWithoutTx()
  3. {
  4.     PersonTestData ptd = new PersonTestData();
  5.     ptd.CreatePersonEntries(3);
  6.  
  7.     m_session = SessionManager.SessionFactory.GetCurrentSession();
  8.     IQueryable<Person> qry = from p in m_session.Query<Person>() select p;
  9.     PersonDAOImpl daoPerson = new PersonDAOImpl(m_session);
  10.     IList<Person> people = daoPerson.GetByQueryable(qry);
  11.  
  12.     Assert.GreaterOrEqual(people.Count, 3);
  13.     people = null;
  14.     daoPerson = null;
  15.     m_session = null;
  16.  
  17.     ptd.RemoveAllPersonEntries();
  18.     ptd = null;
  19. }
PersonDAOImplTests.cs (Pt 7)
  1.         [Test]
  2.         public void PersonDeleteTestWithoutTx()
  3.         {
  4.             m_session = SessionManager.SessionFactory.GetCurrentSession();
  5.             m_session.FlushMode = FlushMode.Commit;
  6.             Person _person = new Person();
  7.             _person.FirstName = "John";
  8.             _person.LastName = "Davidson";
  9.             _person.Email = "jwdavidson@gmail.com";
  10.             _person.UserID = "jwd";
  11.             PersonDAOImpl daoPerson = new PersonDAOImpl(m_session);
  12.             Person newPerson = daoPerson.Save(_person);
  13.  
  14.             Assert.AreEqual(_person, newPerson);
  15.             Console.WriteLine("Person ID: {0}", newPerson.Id);
  16.  
  17.             ICriteria crit = m_session.CreateCriteria(typeof(Person));
  18.             IList<Person> people = daoPerson.GetByCriteria(crit);
  19.  
  20.             Assert.Greater(people.Count, 0);
  21.             Int32 pers = people.Count;
  22.             Console.WriteLine("Count After Add: {0}", pers);
  23.  
  24.             people = null;
  25.             daoPerson.Delete(newPerson);
  26.             newPerson = null;
  27.             people = daoPerson.GetByCriteria(crit);
  28.             Console.WriteLine("Count after Delete: {0}", people.Count);
  29.  
  30.             Assert.IsTrue(pers.Equals(people.Count + 1));
  31.  
  32.             people = null;
  33.             _person = null;
  34.             daoPerson = null;
  35.             m_session = null;
  36.         }
  37.     }
  38. }

Summary

 

 

 

This solution retains all the functionality as was included in the original solution, but it has now been placed in an architecture that improves testability and simplifies the creation of functionality as each element now has a clear project where it belongs within the solution. The next evolution of the bootstrapper will investigate data service usage and more complex mappings. However this version of the bootstrapper is now appropriate to use for simple projects with NHibernate where the domain model is relatively simple.

 

 

If you remember back to the code behind file discussion there were still methods that remained for working with the gridview and drop down controls on the web page. These could be moved up to the presenter if these controls were redesigned as composite controls in a separate project in the solution so that they were no longer inherited through System.Web.


Posted Sun, 05 December 2010 05:59:00 AM by jwdavidson
Filed under: NHibernate, Criteria, linq

comments powered by Disqus
© NHibernate Community 2024