如何测试Nhibernate的扩展方法,即使在指定虚假的返回之后也不返回值? [英] How do I test extension method of Nhibernate which does not return the value even after specifying return in fakeiteasy?

查看:132
本文介绍了如何测试Nhibernate的扩展方法,即使在指定虚假的返回之后也不返回值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  public class MyActualClass 
{
public MyActualClass(ISessionFactory sessionFactory)
{
this.sessionFactory = sessionFactory;
}

公共列表<年度信息> GetData()
{
using(session = sessionFactory.OpenSession())
{
var result = session.QueryOver< AnnualInformation>()
.SelectList(list (x => x.Id)
.Select(x => x.CreationDate)
.Select(x => x.AnnualAmount)
.Select(x => x.AnnualCurrency)
.Select((=)=> monthlyAlias.MonthlyAmount)
.Select(()=> monthlyAlias.MonthlyCurrency)
(()=> shareAlias.CurrentSharevalue)
.Select(()=> miscAlias.MarketValueAmount)
).Where(a => a.Id == 123456).List< AnnualInformation>();





我写了单元测试用例对于上面的方法如下

  public class MyTestClass 
{
private static ISessionFactory sessionFactory;
私有静态ISession会话;

public MyTestClass()
{
sessionFactory = A.Fake< ISessionFactory>();
session = A.Fake< ISession>(); $(b
$ b)A.CallTo(()=> sessionFactory.OpenSession())。

$ b $事实
public void MyTest()
{
var annualDetails =
Annual Annual Information
{
Id = 1,
AnnualCurrency =string,
AnnualAmount =示例
}
var listOfAnnualInformation =
New List< AnnualInformation>
{
annualDetails
};

A.CallTo(session.QueryOver< AnnualInformation>())WithReturnType< IList< AnnualInformation>>()。Returns(listOfAnnualInformation);
var myInstance = new MyActualClass(s​​essionFactory);
myInstance.GetData();






$ b实际上如果你看到下面的代码$ / $>

session.QueryOver()
.SelectList(...



将在方法GetData() 。之后,我操纵结果数据结构获取Id,CreationDate,AnnualAmount,AnnualCurrency

因此,从结果返回一些值是非常重要的。我的问题是结果总数总是0。



我想要下面这行代码:

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

返回一个包含至少一个元素的列表,现在我相信我已经明确了我的要求了。

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

解决方案

基于新的代码完全编译 - 缺少; result 不是从 GetData GetData 应该是 IList< AnnualInformation> ,但是通过这些更改,我能够得到测试运行)我可以提供一些评论:

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

配置调用 session.QueryOver< AnnualInformation> )。 (注意这里没有lambda,所以这一行实际上是调用 QueryOver 。)

session 是假的,所以当你在这一行上调用 QueryOver< AnnualInformation>()时,它将返回一个新的伪 IQueryOver 。当返回 IList< AnnualInformation> 的任何方法时,WithReturnType ... Returns ...配置新的Fake IQueryOver返回 listOfAnnualInformation >被调用。然而,当Fakes的方法被调用时,除非它们被配置为做不同的事情,否则它们会返回一个新的对象。所以当你调用 QueryOver 的时候,在 GetData 里面,会得到一个不同的伪造的 IQueryOver ,它根本没有被配置。第二个问题:调用 SelectList 会返回另一个伪造的 我们可以解决所有这些问题:

 

var aFakeQueryOver = A.Fake< IQueryOver< AnnualInformation,AnnualInformation>>();
A.CallTo(aFakeQueryOver).WithReturnType< IQueryOver< AnnualInformation,AnnualInformation>>()
.Returns(aFakeQueryOver);
A.CallTo(aFakeQueryOver).WithReturnType< IList< AnnualInformation>>()
.Returns(listOfAnnualInformation); ((()=> session.QueryOver< AnnualInformation>()))。返回(aFakeQueryOver);

现在伪造行为就像我们想要的那样。然而,我们所做的只是将 GetData 中的所有逻辑短路,除非看到它使用 sessionFactory 打开会话,然后在该会话中 QueryOver SelectList 其中 List 全部被绕过。 / p>

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


I have a class like below where using Fluent Nhibernate I am getting data from database

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

I Have written unit test case for above method like below

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

Actually if you see below code

session.QueryOver() .SelectList(...

will return "result" in method GetData(). After that I am manipulating "result" datastructure to get Id, CreationDate, AnnualAmount, AnnualCurrency
Therefore it is very important that some value is returned from "result". My problem is the count of resulty is always 0.

I want the below line of code

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

to return a list with atleast one element. Now i believe i clarified my requirements

Please suggest what should be done here ?

解决方案

Based on the new code (which still doesn't quite compile - missing ;, result isn't returned from GetData, and if it were, the return type of GetData should be IList<AnnualInformation>, but with those changes I was able to get a test to run) I can offer some commentary:

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

Configures the object that comes back from calling session.QueryOver<AnnualInformation>(). (Note there's no lambda here, so this line actually calls QueryOver.)
session is a Fake, and so when you call QueryOver<AnnualInformation>() on this line, it will return a new Fake IQueryOver. The "WithReturnType…Returns…" configures the new Fake IQueryOver to return listOfAnnualInformation when any method that returns a IList<AnnualInformation> is called.

However, when Fakes' methods are called, unless they've been configured to do something different, they return a new object. So inside GetData when you call QueryOver, you get a different fake IQueryOver, which has not been configured at all. That's one problem.

Second problem: the call to SelectList will return yet another faked IQueryOver.

We can work around all these things:

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

And now the faking behaves as we want. However, all we've done is short-circuit all the logic in GetData, except to see that it uses the sessionFactory to open a session, and then QueryOver on that session. SelectList and Where and List have all been bypassed.

My usual advice in this situation is to make your data access layer as thin as possible and to integration test it. Alternatively, I've seen people suggest having NHibernate use an in-memory MySql database. Still an integration test of sorts, but at least it's more isolated.

这篇关于如何测试Nhibernate的扩展方法,即使在指定虚假的返回之后也不返回值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆