当模拟`ISession`对象时,出现异常抛出

3

我有以下代码,在其中我尝试给ISession.Query<UnitModel>()打桩。

var unitList = new List<UnitModel>()
            {
                new UnitModel(){Name = "meters", Symbol="m"},
                new UnitModel(){Name="grams", Symbol="g"}
            };

MockRepository.GenerateMock<ISession>().Stub(x => x.Query<UnitModel>()).Return(unitList.AsQueryable<UnitModel>());

运行时,会抛出以下异常:

System.InvalidOperationException : Type 'System.Linq.EnumerableQuery`1[[MIB.DomainModels.UnitModel, MIB, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' doesn't match the return type 'NHibernate.Engine.ISessionImplementor' for method 'ISession.GetSessionImplementation();'

我在这里做错了什么?我应该如何存根ISession.Query<UnitModel>()

NHibernate 3.3.0.4000

编辑:UnitModel类:

public class UnitModel
{
    public virtual string Name { get; set; }
    public virtual string Symbol { get; set; }
}

你能把你的UnitModel类发布在这里吗? - Faraday
2个回答

6

对于模拟ISession来说通常是费时且痛苦的。

Query<T>特别是一个调用ISession.GetSessionImplementation()内部方法的扩展方法,因此您必须模拟它才能使用它(这是非平凡的,并实际上将您绑定到特定实现细节)。

有两个更好的选择:

  1. 实现具有由NHibernate会话支持的实现的存储库接口,并且可以轻松地模拟
    • 优点:功能强大,没有限制
    • 缺点:您可能会发现自己受到自己的抽象或在需要访问特定NH功能时重新发明轮子的限制
  2. 使用内存中或干净的DB进行测试
    • 优点:设置工作量大大减少,您可以访问所有NH功能
    • 缺点:如果使用不同的DB引擎,则某些查询可能具有不同的行为。

除非您已经在使用存储库,否则我的建议是选择#2。


我一开始尝试选择1,但是后来发现我的应用程序需要很多不同的查询,而我的存储库接口看起来就像是ISession本身。然后我选择了2。由于我有NCrunch,即使使用MSSQLServer 2005,测试也几乎没有浪费时间。 - nakiya

0
在你的UnitModel类中实现ISessionImplementor,VisualStudio应该会警告你缺少方法...虽然我不确定它是否会有太大帮助,因为ISessionImplementor是一个内部接口,我相信你不应该使用它!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接