我有可能被视为从我的应用程序堆栈传递的IQueryable<T>
和IList<T>
域对象集合的奇怪混合。我试图保持尽可能多的“迟到查询”或“延迟加载”。我这样做有两种方式:
IQueryable<T>
到我的应用层。IList<T>
之后,但是对象/聚合图中的某些元素是'chained' with delegates,以便推迟加载。有时,即使代理内容依赖IQueryable<T>
来源,也会注入DataContext
。到目前为止,这对我有用。
令人难以置信的是证明这种设计确实有效。 IE浏览器。如果我在某个地方击败'懒惰'部分并且我的评估/执行发生得很早,那么整个事情就是浪费时间。我想以某种方式TDD这个。
我对代理或线程安全知之甚少,因为它适用于代理在同一来源上的代理。我希望能够模拟DataContext
并以某种方式跟踪延迟(IQueryable<T>
的SQL和委托)加载的两种方法,以便我可以进行测试以证明两个函数都在工作在应用程序/堆栈的不同级别/层。
因为延迟对于设计具有任何价值至关重要,所以当我在给定级别(与实时实现分开)中打破设计时,我希望看到测试失败。这可能吗?
答案 0 :(得分:4)
在morelinq,我们有一个所谓的“打破序列”来测试它。基本上,它是一个枚举器,只要枚举它就会抛出异常。
它可以像以下一样简单:
internal sealed class BreakingSequence<T> : IEnumerable<T>
{
public IEnumerator<T> GetEnumerator()
{
throw new InvalidOperationException();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
对它的测试看起来像这样:
[Test]
public void XyzIsLazy()
{
var source = BreakingSequence<EntityClass>().AsQueryable();
// inject it as your query source wherever appropriate
var query = source.Where(x=> true);
// does not throw, where does not enumerate the sequence
}
答案 1 :(得分:2)
我将以与Johannes Rudolph所回答的相似的方式回答。听起来你正在思考正确的事情,想要对重要的事情进行测试,如果它失败则难以追踪。
我肯定会建议为此目的使用模拟器。 Johannes提出了一个在枚举时引发异常的对象。由于您的对象是模板化的,我相信您应该能够使用您想要的任何对象。一个模拟框架,如Rhino.Mocks(免费)或TypeMock Isolator(昂贵),可能会非常有用。如果您还没有,我强烈建议您查看模拟框架。
使用模拟手册,您可以评估在运行某些测试代码时,操作应按特定顺序进行。您可以对模拟进行编程以记录发生的操作,然后在测试结束时检查记录。