6

我有一个奇怪的混合IQueryable<T>IList<T>域对象集合传递到我的应用程序堆栈。我试图尽可能多地维护“延迟查询”或“延迟加载”。我通过两种方式做到这一点:

  1. 通过使用 LinqToSql 数据层并将IQueryable<T>s 通过存储库传递到我的应用程序层。
  2. 然后在我的应用程序层传递IList<T>s 但对象/聚合图中的某些元素与委托“链接”后,以延迟它们的加载。有时甚至委托内容也依赖于IQueryable<T>源并且DataContext被注入。

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

令人眼花缭乱的困难在于证明这种设计确实有效。IE。如果我在某个地方击败了“懒惰”部分并且我的评估/执行发生得早,那么整个事情就是浪费时间。我希望能够以某种方式对此进行 TDD。

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

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

4

2 回答 2

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
    }
于 2010-05-24T09:56:10.127 回答
2

我将以与 Johannes Rudolph 的回答类似的方式回答。听起来你在想正确的事情,想要对一些重要的事情进行测试,如果它失败了就很难追踪。

我肯定会建议为此目的使用模拟。Johannes 提出了一个在枚举时抛出异常的对象。由于您的对象是模板化的,我相信您应该能够使用您想要的任何对象。一个模拟框架,例如 Rhino.Mocks(免费)或 TypeMock Isolator(昂贵),可能会很有帮助。如果您还没有,我强烈建议您研究模拟框架。

有了一个模拟,您可以评估在运行某些测试代码时操作应该以特定顺序发生。您可以编写模拟程序来记录发生的操作,然后在测试结束时检查记录。

于 2010-05-28T14:22:35.207 回答