如何测试Nhibernate的扩展方法,即使在fakeiteasy中指定return后也没有返回值?

我有一个像下面这样的类使用Fluent Nhibernate我从数据库中获取数据

public class MyActualClass { public MyActualClass(ISessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } public List GetData() { using (session = sessionFactory.OpenSession()) { var result = session.QueryOver() .SelectList(list => list .Select(x => x.Id) .Select(x => x.CreationDate) .Select(x => x.AnnualAmount) .Select(x => x.AnnualCurrency) .Select(() => monthlyAlias.MonthlyAmount) .Select(() => monthlyAlias.MonthlyCurrency) .Select(() => shareAlias.CurrentSharevalue) .Select(() => miscAlias.MarketValueAmount) ).Where(a => a.Id == 123456).List(); } } } 

我已经为上面的方法编写了unit testing用例,如下所示

 public class MyTestClass { private static ISessionFactory sessionFactory; private static ISession session; public MyTestClass() { sessionFactory = A.Fake(); session = A.Fake(); A.CallTo(() => sessionFactory.OpenSession()).Returns(session); } [Fact] public void MyTest() { var annualDetails = new AnnualInformation { Id= 1, AnnualCurrency= "string", AnnualAmount= "Example" } var listOfAnnualInformation= new List { annualDetails }; A.CallTo(session.QueryOver()).WithReturnType<IList>().Returns(listOfAnnualInformation); var myInstance = new MyActualClass(sessionFactory); myInstance.GetData(); } } 

实际上,如果你看到下面的代码

session.QueryOver().SelectList(…

将在方法GetData()中返回“result”。 之后我操纵“结果”数据结构来获得Id,CreationDate,AnnualAmount,AnnualCurrency
因此,从“结果”返回一些值非常重要。 我的问题是结果的计数总是0。

我想要下面的代码行

。A.CallTo(session.QueryOver())WithReturnType>()返回(listOfAnnualInformation);

返回一个包含至少一个元素的列表。 现在我相信我澄清了我的要求

请建议在这里做什么?

基于新代码(仍然没有完全编译 – 缺少; result不是从GetData返回的,如果是,则GetData的返回类型应该是IList ,但是通过这些更改,我能够得到一个测试运行)我可以提供一些评论:

 A.CallTo(session.QueryOver()).WithReturnType>() .Returns(listOfAnnualInformation); 

配置从调用session.QueryOver()返回的对象。 (注意这里没有lambda,所以这一行实际上调用了QueryOver 。)
session是假的,所以当你在这一行上调用QueryOver()时,它将返回一个新的Fake IQueryOver 。 当listOfAnnualInformation任何返回IList方法时,“WithReturnType … Returns …”将新的Fake IQueryOver配置为返回listOfAnnualInformation

但是,当调用Fakes的方法时,除非它们被配置为执行不同的操作,否则它们将返回一个新对象。 因此,当您调用QueryOver ,在GetData内部,您会得到一个不同的假IQueryOver ,它根本没有配置。 这是一个问题。

第二个问题:对SelectList的调用将返回另一个伪造的IQueryOver

我们可以解决所有这些问题:

 var aFakeQueryOver = A.Fake>(); A.CallTo(aFakeQueryOver).WithReturnType>() .Returns(aFakeQueryOver); A.CallTo(aFakeQueryOver).WithReturnType>() .Returns(listOfAnnualInformation); A.CallTo((() => session.QueryOver())).Returns(aFakeQueryOver); 

现在,假装表现得像我们想要的那样。 但是,我们所做的只是将GetData所有逻辑短路,除了看到它使用sessionFactory打开一个会话,然后在该会话上使用QueryOverSelectList以及WhereList都被绕过了。

在这种情况下,我通常的建议是使您的数据访问层尽可能薄,并进行集成测试。 或者,我看到有人建议让NHibernate使用内存中的MySql数据库。 仍然是各种各样的集成测试,但至少它更加孤立。