[英]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的建議並且做到了這一點,但是因為IQuery
被IQuery
轉換為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.