开发者

Implement a fake NHibernate repository

I am using StoryQ to perform some basic integration testing and we are using NHibernate as our ORM. When I started, I didn't know that NHibernate implemented the Repository pattern and so I created my own IRepository in order to run my integration tests.

However, considering that NHibernate already implements the Repository patt开发者_StackOverflowern, I assume that it is doing so against some kind of interface. So, I would like to work against NHibernate's interface for the Repository if my assumptions are correct.

I have tried to search for it but I come across information that to do that I need to work against the ISession interface. As I do not really know NHibernate that well, can someone explain why I would need to implement my fake repository against the ISession interface? What is the IRepository equivalent in NHibernate? Is there some tutorial which goes into greater depth into the matter?


NHibernate doesn't implement the Repository pattern. It replaces it.

SQLite in-memory databases are nice if you've got a simple database implementation, but I've found that things can become cumbersome quickly, almost to a point where it becomes as painful, if not more, to use SQLite as it is to stub/mock ISession/ICriteria/etc.

One perfect example of this: In one of my recent projects, in which I was using PostgreSQL as my production database and SQLite as my test database, I had a need to extend NHibernate to add support for an aggregate function that was recently added to PostgreSQL. Figuring out how to add this was a story in itself, but I worked it out. I then had to find a functional equivalent in SQLite. I needed an aggregate function that worked in the same exact way as its Postgres counterpart. There was none. I asked around and was told that there were ways to extend NHibernate to "fake" this function in SQLite. I also had the option of extending SQLite to add this functionality.

All I wanted to do was write two, maybe three, tests around the scenario that I was trying to implement. I ended up spending way too much time trying to ensure functional equivalency between the two systems. It wasn't worth all this effort for one function. And what would happen if down the road, I needed to add another function?

I think SQLite is useful. It's a great lightweight database system and I love that you can conveniently use it as a in-memory database for simple scenarios. However, I'm not sure it's worth using beyond that. I think from now on, I'll be using the same database across all environments, even if it means having slower integration tests for all data persistence logic.


I'm not sure where in core NHibernate there is an IRepository interface (AFAIK there's none) so you might be referring some other NHibernate side projects.

It is not the best approach to go about mocking ISession either. The best thing in my opinion, is to use a real in-memory database that is fully supported by NHibernate. You may need to check how to configure NHibernate to run on sqlite in-memory database, which basically is just configuring NHibernate in your tests.

The good thing about this approach, is that tests run with a very good speed, as if there's no database involved, and you don't need to abstract away all your ORM functionality (and loose features too) just to run / drive your tests.


The approach I've taken is to implement an IRepository and GenericRepository, to wrap the ISession Save and Delete methods. Also, GenericRepository also implements IQueryable using NHibernate's LINQ provider. My implementation borrows heavily from Javier Lozano's MVC Trubine project. His implementation is here: https://github.com/jglozano/mvcturbine/blob/master/src/Blades/NHibernate/MvcTurbine.NHibernate/GenericRepository.cs

This works for about 80% of the queries I need. For the rest, I create a Query Object to wrap the query. That way, I can use ICriteria, IQuery, IQueryOver or LINQ, whichever the needs of the query dictate. Fabio Maulo explains it pretty well here: http://fabiomaulo.blogspot.com/2010/07/enhanced-query-object.html

Both approaches allow easily mocking away the dependency.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜