我如何模拟或测试我的延期评估/执行功能?

Mat*_*caj 6 testing tdd delegates linq-to-sql deferred-execution

我有可能被视为奇怪的混合IQueryable<T>IList<T>域对象集合传递给我的应用程序堆栈.我试图保持尽可能多的"迟到查询"或"延迟加载".我这样做有两种方式:

  1. 通过使用LinqToSql数据层并通过IQueryable<T>存储库传递到我的应用层.
  2. 然后在我的app层传递IList<T>s后,但是对象/聚合图中某些元素与代理"链接"以便推迟加载.有时甚至委托内容依赖于IQueryable<T>源和DataContext注入.

到目前为止,这对我有用.

令人难以置信的是证明这种设计确实有效.IE浏览器.如果我在某个地方击败'懒惰'部分并且我的评估/执行发生得很早,那么整个事情就是浪费时间.我想以某种方式TDD这个.

我不太了解委托或线程安全,因为它适用于代理人在同一来源上行事.我希望能够模拟DataContext并以某种方式跟踪延迟(IQueryable<T>的SQL和委托)加载的两种方法,以便我可以进行测试,证明两个函数都在app/stack的不同级别/层工作.

由于延迟对于设计有任何价值至关重要,我希望当我在给定级别上破坏设计时(与实时实现分开),测试失败.这可能吗?

Joh*_*lph 4

morelinq,我们有一个所谓的“中断序列”来测试这一点。基本上,它是一个枚举器,每当枚举它时就会抛出异常。

它可以很简单:

internal sealed class BreakingSequence<T> : IEnumerable<T>
{
    public IEnumerator<T> GetEnumerator()
    {
        throw new InvalidOperationException();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}
Run Code Online (Sandbox Code Playgroud)

对其进行的测试如下所示:

   [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
    }
Run Code Online (Sandbox Code Playgroud)