我有一个像下面这样的类,使用Fluent Nhibernate我从数据库中获取数据
public class MyActualClass
{
public MyActualClass(ISessionFactory sessionFactory)
{
this.sessionFactory = sessionFactory;
}
public List<AnnualInformation> GetData()
{
using (session = sessionFactory.OpenSession())
{
var result = session.QueryOver<AnnualInformation>()
.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<AnnualInformation>();
}
}
}
我已经为上面的方法编写了单元测试用例,如下所示
public class MyTestClass
{
private static ISessionFactory sessionFactory;
private static ISession session;
public MyTestClass()
{
sessionFactory = A.Fake<ISessionFactory>();
session = A.Fake<ISession>();
A.CallTo(() => sessionFactory.OpenSession()).Returns(session);
}
[Fact]
public void MyTest()
{
var annualDetails =
new AnnualInformation
{
Id= 1,
AnnualCurrency= "string",
AnnualAmount= "Example"
}
var listOfAnnualInformation=
new List<AnnualInformation>
{
annualDetails
};
A.CallTo(session.QueryOver<AnnualInformation>()).WithReturnType<IList<AnnualInformation>>().Returns(listOfAnnualInformation);
var myInstance = new MyActualClass(sessionFactory);
myInstance.GetData();
}
}
实际上,如果你看到下面的代码
session.QueryOver() .SelectList(...
将在方法GetData()中返回“result”。之后我操纵“结果”数据结构来获得Id,CreationDate,AnnualAmount,AnnualCurrency
因此,从“结果”返回一些值非常重要。我的问题是结果的计数总是为0。
我想要下面的代码行
A.CallTo(session.QueryOver())WithReturnType&GT;()返回(listOfAnnualInformation)。
返回包含至少一个元素的列表。现在我相信我澄清了我的要求
请建议应该在这做什么?
答案 0 :(得分:2)
基于新代码(仍然没有完全编译 - 缺少;
,result
不会返回GetData
,如果是,则返回类型{ {1}} GetData
应该是IList<AnnualInformation>
,但是通过这些更改我可以进行测试运行)我可以提供一些评论:
A.CallTo(session.QueryOver<AnnualInformation>()).WithReturnType<IList<AnnualInformation>>()
.Returns(listOfAnnualInformation);
配置从调用session.QueryOver<AnnualInformation>()
返回的对象。 (注意这里没有lambda,所以这一行实际上调用QueryOver
。)
session
是假的,因此当您在此行上致电QueryOver<AnnualInformation>()
时,它会返回新的假IQueryOver
。当调用任何返回listOfAnnualInformation
的方法时,“WithReturnType ... Returns ...”将新的Fake IQueryOver配置为返回IList<AnnualInformation>
。
但是,当调用Fakes的方法时,除非它们被配置为执行不同的操作,否则它们将返回一个新对象。因此,当您致电GetData
时,在QueryOver
内,您会得到一个不同的假IQueryOver
,但根本没有配置。这是一个问题。
第二个问题:对SelectList
的调用将返回另一个伪造的IQueryOver
。
我们可以解决所有这些问题:
var aFakeQueryOver = A.Fake<IQueryOver<AnnualInformation, AnnualInformation>>();
A.CallTo(aFakeQueryOver).WithReturnType<IQueryOver<AnnualInformation, AnnualInformation>>()
.Returns(aFakeQueryOver);
A.CallTo(aFakeQueryOver).WithReturnType<IList<AnnualInformation>>()
.Returns(listOfAnnualInformation);
A.CallTo((() => session.QueryOver<AnnualInformation>())).Returns(aFakeQueryOver);
现在假装表现得像我们想要的那样。但是,我们所做的只是将GetData
中的所有逻辑短路,除了看到它使用sessionFactory
打开会话,然后QueryOver
在该会话上。 <{1}}和SelectList
以及Where
都被绕过了。
在这种情况下,我通常的建议是尽可能减少数据访问层并对其进行集成测试。或者,我见过人们建议让NHibernate使用内存中的MySql数据库。仍然是各种各样的集成测试,但至少它更加孤立。