How are Moq NHibernate Extension Methods?

I am developing an application using NHibernate for ORM, NUnit for unit testing, and Ninject for my DI. I am mocking ISession:

var session = new Mock<ISession>(); 

With regular non-mocked session objects, I can query them using LINQ extension methods as follows:

 var result = Session.Query<MyEntity>(); 

But when I try to make fun of it with the following code ...

 session.Setup(s => s.Query<MyEntity>()); 

... I get the "Not Supported" exception:

 Expression references a method that does not belong to the mocked object: s => s.Query<MyEntity>() 

How can I mock such basic queries in Moq / NHibernate?

+4
source share
2 answers

Query<T>() is an extension method, so you cannot mock it. Although @Roger's answer is a way to go, it is sometimes useful to have specific tests. You can start exploring what the Query<T>() method does - either by reading NHibernate code or using your own tests, and set the appropriate methods for ISession.

Warning: creating such a setting will make your test very fragile and it will break if the internal implementation of NHibernate changes.

In any case, you can start your investigation with:

 var mockSession = new Mock<ISession>(MockBehavior.Strict); //this will make the mock to throw on each invocation which is not setup var entities = mockSession.Object.Query<MyEntity>(); 

The second line above will throw an exception and show you which actual property / method on ISession trying to use the Query<T>() extension method, so you can set it accordingly. Keep going this way, and you will end up with a good setup for your session so that you can use it in the test.

Note. I am not familiar with NHibernate, but I used the above approach when I had to deal with extension methods from other libraries.

+3
source

I tried Sunny's suggestion and got it far, but got stuck since IQuery dropped into NHibernate.Impl.ExpressionQueryImpl , which is internal, and I don't think it can be expanded. Just post it to save the other lost souls for a couple of hours.

 var sessionImplMock = new Mock<NHibernate.Engine.ISessionImplementor>(MockBehavior.Strict); var factoryMock = new Mock<NHibernate.Engine.ISessionFactoryImplementor>(MockBehavior.Strict); var queryMock = new Mock<IQuery>(MockBehavior.Strict);//ExpressionQueryImpl sessionImplMock.Setup(x => x.Factory).Returns(factoryMock.Object); sessionImplMock.Setup(x => x.CreateQuery(It.IsAny<IQueryExpression>())).Returns(queryMock.Object); sessionMock.Setup(x => x.GetSessionImplementation()).Returns(sessionImplMock.Object); 
+1
source

Source: https://habr.com/ru/post/1478977/


All Articles