Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking NHibernate & Linq

I'm using NHibernate and exposed the Session in my front end. I have a controller action which retrieves tasks as follows:

public ActionResult Overview(DateTime date)
{
    var allTasks = GetTasksUpUntilDate(date);
    return PartialView("Tasks/Overview", allTasks);
}

private List<TaskOverviewModel> GetTasksUpUntilDate(DateTime date)
{            
    var allTasks = _session.Query<Task>().Where(t.BookedBy.UserName.Equals(CurrentUser.Name,
                                       StringComparison.CurrentCultureIgnoreCase));            
    var tasks = allTasks.Where(t => t.DueDate <= date);

    var taskVMs = new List<TaskOverviewModel>();        
    tasks.ForEach(t => taskVMs.Add(MapEntityToViewModel(t)));

    return taskVMs;
}

Now I don't want to create an IRepository just for my views since ISession actually already is a repository. Mocking/stubbing this however is proving rather hard. So can anyone help me to have _session.Query return a list of objects I provide while testing?.

I'd also like to avoid setting up an in memory database and am using RhinoMocks for my tests.

like image 810
Mirage Avatar asked Mar 06 '12 12:03

Mirage


2 Answers

Dont fake Nh/linq. Instead setup an in-memory sqlite db to query against. They are extremely fast and easy to use.

like image 144
Jason Meckley Avatar answered Sep 28 '22 05:09

Jason Meckley


NHibernate Session might fit the repository pattern, but if you are building your controllers to talk to it directly, you are not truly abstracting it. Mocking it when you aren't abstracting it is not a reliable solution.

If you absolutely don't want to abstract it (which is pure lazy, IMO), then the sqllite db as mentioned by Jason is a good call. However, on a large project properly separating your concerns is very much a good idea.

My domain model contains the interfaces for both the data access objects (repos) and the services which consume them. This allows me to truly separate my data concerns from my business concerns, which should be entirely separated from the view/app concerns. This allows proper unit testing and the ability to easily swap out parts or do proper mocking.

Each layer ONLY talks to interfaces, NEVER to an implementation. Furthermore my application layer never talks directly to the data layer - only services. Allowing that to happen seems to encourage developers to be lazy and start putting business or data logic into the application.

like image 40
Chad Ruppert Avatar answered Sep 28 '22 06:09

Chad Ruppert