如何测试 Nhibernate 的扩展方法,该方法即使在 fakeiteasy 中指定返回后也不会返回值

本文关键字:方法 fakeiteasy 返回 返回值 测试 何测试 Nhibernate 扩展 | 更新日期: 2023-09-27 18:25:10

>我有一个像下面这样的类,使用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();
    }
}  

实际上,如果您看到以下代码

会期。查询结束(( .选择列表(...

将在方法 GetData(( 中返回"结果"。之后,我正在操纵"结果"数据结构以获取Id,创建日期,年度金额,年度货币
因此,从"结果"返回一些值非常重要。我的问题是结果计数始终为 0。

我想要下面的代码行

A.呼叫(会话。QueryOver(((。WithReturnType>((。回报(年度信息列表(;

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

请建议在这里应该做什么?

如何测试 Nhibernate 的扩展方法,该方法即使在 fakeiteasy 中指定返回后也不会返回值

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

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

配置从调用 session.QueryOver<AnnualInformation>() 返回的对象。(请注意,这里没有 lambda,所以这一行实际上调用 QueryOver
session是假的,所以当你在这个线路上调用QueryOver<AnnualInformation>()时,它会返回一个新的假IQueryOver。"与返回类型...返回..."将新的 Fake IQueryOver 配置为在调用任何返回IList<AnnualInformation>的方法时返回listOfAnnualInformation

但是,当调用 Fake 的方法时,除非它们被配置为执行不同的操作,否则它们会返回一个新对象。所以在里面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打开会话,然后在该会话上QueryOverSelectListWhereList都被绕过了。

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