NHibernate Unit Testing Mocking / In Memory Database

I am trying to learn how to mock my shared repository so that I can unit test run all my services.

Im using NHibernate Fluent to handle data access and Ninject for dependency (I'm not interested in testing)

My repository interface looks like this:

public interface IRepository<TEntity> where TEntity : class { IQueryable<TEntity> GetAll(); TEntity Get(int key); void Insert(TEntity entity); void Update(TEntity entity); void Delete(int id); } 

And the actual repository is as follows:

 public class GenerRepository<TEntity> : IRepository<TEntity>where TEntity : Entity { protected ISession Session{get { return NHibernateHelper.OpenSession(); }} public IQueryable<TEntity> GetAll(){return Session.Query<TEntity>();} public TEntity Get(int key){return Session.Get<TEntity>(key);} public void Insert(TEntity entity){Session.Save(entity);} public void Update(TEntity entity){Session.Update(entity);} public void Delete(int id){Session.Delete(Session.Load<TEntity>(id));} } 

All my services do the following: create a repository and use it.

I have read so many articles on how to do this, but none of them are simple or explained. Therefore, any advice between creating a test universal repository or even mocking it. I would also be interested in creating a database in memory, but how do I configure for free nhibernate in my test project without editing the code in my real project?

Is it possible for the shared repository to go to the Tentity list, and not to the database or the database.

Thanks for reading and look forward to hearing.

+6
source share
3 answers

There are several ways to achieve this,

  • Use this database for testing using scripts to set up and restore the database, but with this approach it will take time and effort to create and maintain these scripts when making changes to the database

  • Use a real database and use the transaction scope for testing (the start of the transaction is saved and the test is executed, and as soon as everything is done only with the rollback of the transaction), this is a really good approach, and I use this for a large-scale project. However, one of the problems is that it takes a long time to run the tests (I have about 3,500 tests, and it only takes 40 minutes to run them)

  • Use fake repositories (with an internal list of entities) to test business logic and actually use repositories to verify mappings. This approach will require additional efforts to create and maintain fake repositories. The same tests performed in real repositories can be performed on fake repositories to check forgery. With this approach, the test will be faster.

+4
source

I have to agree with Radim that the nhibernate code testing module, making fun of nhibernate functionality in most cases, is not what you want to do.

If you donโ€™t want to test complex business logic based on the data you extract using nhibernate, then this is perfectly normal.

But to check if your mappings, search and save data work, you need to test a real database.

If you aim at MSSQL Server, I would not use another type of database. Instead, there is SQL Express, which has all the features of a real server. MSSQL Express can be installed from a local database. This will allow you to download mdf files through the connection string, which will more or less create an instance of the MSSQL server ...

I used this to test integration, and it works very well.

  • Create a database file in a unit test project
  • Depending on your model (/ db code first), let nhibernate create a schema, otherwise just fill in the schema in this database file
  • Add the file to the deployment elements of your test settings so that the file is copied to the target destination directory
  • Create a connection string that uses the copied database file. Example connection string: Data Source=(LocalDB)\v11.0;AttachDbFileName=[whateverthepathis]\DatabaseFileName.mdf;InitialCatalog=DatabaseName;Integrated Security=True;MultipleActiveResultSets=True
  • Run tests

Thus, your tests will be run with an empty database every time, and you will have reproducible integration tests without the need for a real server, where you had to create a database or reset each time ...

+6
source

My answer should / may be a comment, maybe. Because I would like to tell you: do not do this . Do not waste time creating a fake of data that needs to be returned with preservation. And do not waste time trying to: take data from the client and put it in a virtual database in memory.

You must be sure that your services (using the repository) can really serialize / display real data. And deserialize / save changed. And it really will require real data.

Rather, spend some time creating scripts that will populate the test data. The data you can expect in your tests: when doing business, serializing service data ...

Also see here: Ayende: NHibernate module testing . Exposure:

When using NHibernate, we usually want to test only three things that the properties are saved, this cascade works as expected, and that the queries return the correct result. To do all this, we usually have to talk to a real database, trying to fake any of these at this level is useless and will be very difficult.

Note: some time ago we used all the tests in the transaction Begin() and Rollback() . It looked good. But we realized that a lot of things - due to the lack of Flush() call - have not been fully tested (for example, setting non-null).

+4
source

All Articles