使用Moq模拟nHibernate QueryOver
测试时,以下行以空引用失败:
var awards = _session.QueryOver().Where(x => x.BusinessId == (int)business).List();
我的测试是这样的:
var mockQueryOver = new Mock<IQueryOver>(); mockQueryOver.Setup(q => q.List()).Returns(new List {_awardingBody}); _mockSession.Setup(c => c.QueryOver()).Returns((mockQueryOver.Object)); _mockCommandRunner = new Mock(); _generator = new CertificateGeneratorForOpenSSLCommandLine(_mockSession.Object, _mockCommandRunner.Object, _mockDirectory.Object, _mockFile.Object, _mockConfig.Object);
老实说,我在黑暗中徘徊 – 我对nHibernate和Moq相对较新,所以我不太确定谷歌要获取正确的信息。
我不认为上面的代码是对的。 AFAIK QueryOver是ISession接口上的一个扩展方法,你不能像那样模拟扩展方法(至少不能使用传统的Mocking工具,比如Moq或RhinoMocks)。
这不是一个好主意。 你不应该嘲笑你不拥有的类型 。 相反,您应该引入一个Repository ,将其接口基于域/业务语言,并使用NHibernate实现它。 实现可以使用ICriteria,HQL,QueryOver,Linq等。重点是这个决定将被封装并隐藏在使用存储库的代码中。
您可以编写一个集成测试来测试您的接口+ Real ORM + Real或Fake数据库的组合。 请看一下这个以及关于测试存储库和数据访问的答案。 测试使用Repository的代码也非常简单,因为您可以模拟Repository接口。
除了可测试性之外,这种方法有哪些优点? 它们彼此有些相关:
我过去曾使用过几种方法。 正如其他人所建议的那样,一种方法是创建一个Repository类,您可以使用mock / stub封装查询。 这样做的一个问题是,它不是非常灵活,你最终会有一个类似于解决方案的存储过程,除了这个是代码而不是数据库。
我尝试过的最新解决方案是在创建QueryOver存根时创建一个QueryOver存根。 然后,我可以提供应该返回的项目列表。 请记住,如果使用此方法,您不仅应编写unit testing,还应编写集成测试,以测试查询是否真正有效。
public class QueryOverStub : IQueryOver { private readonly TRoot _singleOrDefault; private readonly IList _list; private readonly ICriteria _root = MockRepository.GenerateStub(); public QueryOverStub(IList list) { _list = list; } public QueryOverStub(TRoot singleOrDefault) { _singleOrDefault = singleOrDefault; } public ICriteria UnderlyingCriteria { get { return _root; } } public ICriteria RootCriteria { get { return _root; } } public IList List() { return _list; } public IList List() { throw new NotImplementedException(); } public IQueryOver ToRowCountQuery() { throw new NotImplementedException(); } public IQueryOver ToRowCountInt64Query() { throw new NotImplementedException(); } public int RowCount() { return _list.Count; } public long RowCountInt64() { throw new NotImplementedException(); } public TRoot SingleOrDefault() { return _singleOrDefault; } public U SingleOrDefault () { throw new NotImplementedException(); } public IEnumerable Future() { return _list; } public IEnumerable Future() { throw new NotImplementedException(); } public IFutureValue FutureValue() { throw new NotImplementedException(); } public IFutureValue FutureValue() { throw new NotImplementedException(); } public IQueryOver Clone() { throw new NotImplementedException(); } public IQueryOver ClearOrders() { return this; } public IQueryOver Skip(int firstResult) { return this; } public IQueryOver Take(int maxResults) { return this; } public IQueryOver Cacheable() { return this; } public IQueryOver CacheMode(CacheMode cacheMode) { return this; } public IQueryOver CacheRegion(string cacheRegion) { return this; } public IQueryOver And(Expression> expression) { return this; } public IQueryOver And(Expression> expression) { return this; } public IQueryOver And(ICriterion expression) { return this; } public IQueryOver AndNot(Expression> expression) { return this; } public IQueryOver AndNot(Expression> expression) { return this; } public IQueryOverRestrictionBuilder AndRestrictionOn(Expression> expression) { throw new NotImplementedException(); } public IQueryOverRestrictionBuilder AndRestrictionOn(Expression> expression) { throw new NotImplementedException(); } public IQueryOver Where(Expression> expression) { return this; } public IQueryOver Where(Expression> expression) { return this; } public IQueryOver Where(ICriterion expression) { return this; } public IQueryOver WhereNot(Expression> expression) { return this; } public IQueryOver WhereNot(Expression> expression) { return this; } public IQueryOverRestrictionBuilder WhereRestrictionOn(Expression> expression) { return new IQueryOverRestrictionBuilder(this, "prop"); } public IQueryOverRestrictionBuilder WhereRestrictionOn(Expression> expression) { return new IQueryOverRestrictionBuilder(this, "prop"); } public IQueryOver Select(params Expression>[] projections) { return this; } public IQueryOver Select(params IProjection[] projections) { return this; } public IQueryOver SelectList(Func, QueryOverProjectionBuilder > list) { return this; } public IQueryOverOrderBuilder OrderBy(Expression> path) { return new IQueryOverOrderBuilder(this, path); } public IQueryOverOrderBuilder OrderBy(Expression> path) { return new IQueryOverOrderBuilder(this, path, false); } public IQueryOverOrderBuilder OrderBy(IProjection projection) { return new IQueryOverOrderBuilder(this, projection); } public IQueryOverOrderBuilder OrderByAlias(Expression> path) { return new IQueryOverOrderBuilder(this, path, true); } public IQueryOverOrderBuilder ThenBy(Expression> path) { return new IQueryOverOrderBuilder(this, path); } public IQueryOverOrderBuilder ThenBy(Expression> path) { return new IQueryOverOrderBuilder(this, path, false); } public IQueryOverOrderBuilder ThenBy(IProjection projection) { return new IQueryOverOrderBuilder(this, projection); } public IQueryOverOrderBuilder ThenByAlias(Expression> path) { return new IQueryOverOrderBuilder(this, path, true); } public IQueryOver TransformUsing(IResultTransformer resultTransformer) { return this; } public IQueryOverFetchBuilder Fetch(Expression> path) { return new IQueryOverFetchBuilder(this, path); } public IQueryOverLockBuilder Lock() { throw new NotImplementedException(); } public IQueryOverLockBuilder Lock(Expression> alias) { throw new NotImplementedException(); } public IQueryOver JoinQueryOver(Expression> path) { return new QueryOverStub(new List()); } public IQueryOver JoinQueryOver(Expression> path) { return new QueryOverStub(new List()); } public IQueryOver JoinQueryOver(Expression> path, Expression> alias) { return new QueryOverStub(_list); } public IQueryOver JoinQueryOver (Expression> path, Expression> alias) { return new QueryOverStub(new List()); } public IQueryOver JoinQueryOver(Expression> path, JoinType joinType) { return new QueryOverStub(new List()); } public IQueryOver JoinQueryOver(Expression> path, JoinType joinType) { return new QueryOverStub(new List()); } public IQueryOver JoinQueryOver(Expression> path, Expression> alias, JoinType joinType) { return new QueryOverStub(new List()); } public IQueryOver JoinQueryOver(Expression> path, Expression> alias, JoinType joinType) { return new QueryOverStub(new List()); } public IQueryOver JoinQueryOver(Expression>> path) { return new QueryOverStub(new List()); } public IQueryOver JoinQueryOver(Expression>> path) { return new QueryOverStub(new List()); } public IQueryOver JoinQueryOver(Expression>> path, Expression> alias) { return new QueryOverStub(new List()); } public IQueryOver JoinQueryOver(Expression>> path, Expression> alias) { return new QueryOverStub(new List()); } public IQueryOver JoinQueryOver(Expression>> path, JoinType joinType) { return new QueryOverStub(new List()); } public IQueryOver JoinQueryOver(Expression>> path, JoinType joinType) { return new QueryOverStub(new List()); } public IQueryOver JoinQueryOver(Expression>> path, Expression> alias, JoinType joinType) { return new QueryOverStub(new List()); } public IQueryOver JoinQueryOver(Expression>> path, Expression> alias, JoinType joinType) { return new QueryOverStub(new List()); } public IQueryOver JoinAlias(Expression> path, Expression> alias) { return this; } public IQueryOver JoinAlias(Expression> path, Expression> alias) { return this; } public IQueryOver JoinAlias(Expression> path, Expression> alias, JoinType joinType) { return this; } public IQueryOver JoinAlias(Expression> path, Expression> alias, JoinType joinType) { return this; } public IQueryOverSubqueryBuilder WithSubquery { get { return new IQueryOverSubqueryBuilder(this); } } public IQueryOverJoinBuilder Inner { get { return new IQueryOverJoinBuilder(this, JoinType.InnerJoin); } } public IQueryOverJoinBuilder Left { get { return new IQueryOverJoinBuilder(this, JoinType.LeftOuterJoin); } } public IQueryOverJoinBuilder Right { get { return new IQueryOverJoinBuilder(this, JoinType.RightOuterJoin); } } public IQueryOverJoinBuilder Full { get { return new IQueryOverJoinBuilder(this, JoinType.FullJoin); } } }
不要试图模拟QueryOver。 相反,定义存储库接口(在内部使用QueryOver)并模拟该接口。
最近我一直在将调用.QueryOver()的代码移动到受保护的虚拟方法,并构建我自己的inheritance自XYZ的TestableXYZ并覆盖该方法并返回一个空列表或其他任何内容。 这样我就不需要存储库来进行测试。
上述就是C#学习教程:使用Moq模拟nHibernate QueryOver分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1023644.html