Search code examples
c#nhibernaterhino-mocks

Exception thrown when stubbing mocked `ISession` object


I have the following code where I try to stub ISession.Query<UnitModel>().

var unitList = new List<UnitModel>()
            {
                new UnitModel(){Name = "meters", Symbol="m"},
                new UnitModel(){Name="grams", Symbol="g"}
            };

MockRepository.GenerateMock<ISession>().Stub(x => x.Query<UnitModel>()).Return(unitList.AsQueryable<UnitModel>());

When running, this throws the exception:

System.InvalidOperationException : Type 'System.Linq.EnumerableQuery`1[[MIB.DomainModels.UnitModel, MIB, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' doesn't match the return type 'NHibernate.Engine.ISessionImplementor' for method 'ISession.GetSessionImplementation();'

What am I doing wrong here? How should I go about stubbing ISession.Query<UnitModel>()?

NHibernate 3.3.0.4000

Edit: UnitModel class:

public class UnitModel
{
    public virtual string Name { get; set; }
    public virtual string Symbol { get; set; }
}

Solution

  • Mocking ISession is usually costly and painful.

    Query<T>, in particular, is an extension method that calls ISession.GetSessionImplementation() internally, so you'd have to mock that to work with it (which is non-trivial and actually ties you to a specific implementation detail)

    There are two better alternatives:

    1. Implement a repository interface that has an implementation backed by the NHibernate session, and can be easily mocked
      • Pros: powerful, no limitations
      • Cons: you might find yourself limited by your own abstraction or reinventing the wheel when you need access to specific NH features
    2. Use an in-memory or clean DB for testing
      • Pros: much less work to setup, you have access to all NH features
      • Cons: if you use a different DB engine, some queries might have a different behavior.

    Unless you are already using repositories, my advice is to go with #2.