簡體   English   中英

如何使用Moq NHibernate擴展方法?

[英]How to Moq NHibernate extension methods?

我正在使用NHibernate為ORM開發應用程序,使用NUnit進行單元測試,為我的DI開發Ninject。 我這樣嘲笑ISession:

var session = new Mock<ISession>();

使用常規的非模擬會話對象,我可以使用LINQ擴展方法查詢它們,如下所示:

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

但是,當我嘗試用以下代碼模擬這個...

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

...我得到一個運行時“不支持”的例外:

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

如何在Moq / NHibernate中模擬這樣的基本查詢?

Query<T>()是一種擴展方法,這就是為什么你不能模擬它。 雖然@Roger的答案是可行的,但有時候進行特定測試會很有用。 您可以通過閱讀NHibernate代碼或使用自己的測試開始調查Query<T>()方法的作用,並在ISession上設置適當的方法。

警告:創建這樣的設置將使您的測試非常脆弱,如果NHibernate的內部實現發生變化,它將會中斷。

無論如何,你可以開始調查:

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>();

上面的第二行將拋出異常並顯示Query<T>()擴展方法嘗試訪問的ISession的實際屬性/方法,因此您可以相應地設置它。 繼續這樣,最終你會有一個很好的會話設置,所以你可以在測試中使用它。

注意:我不熟悉NHibernate,但是當我不得不處理來自其他庫的擴展方法時,我已經使用了上述方法。

版本5的更新:

在新的NHibernate版本中, Query<T>是ISession接口的一部分,而不是擴展函數,所以應該很容易模擬。

老答案:

我嘗試了Sunny的建議並且做到了這一點,但是因為IQueryIQuery轉換為NHibernate.Impl.ExpressionQueryImpl ,這是內部的,我不認為可以擴展。 只需發布此信息即可將其他失去的靈魂保存幾個小時。

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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM