模拟 ObjectContext,处理 ObjectQuery.Include(string) 方法?

发布于 2024-09-03 21:18:42 字数 999 浏览 4 评论 0原文

我一直在研究如何将我的 DomainServices 与其数据源分离,以便我可以在单元测试中测试它们。我开始认为将它们完全脱钩是不可能的。

那里有大量的信息,例如这个 问题 和这个 博客文章。这篇博文特别让您深入了解模拟 ObjectContext。

但我的 DomainServices 有这样的方法:

public IQueryable<Client> GetClients()
{
    return ObjectContext.Clients
        .Include("Foo")
        .Include("Bar")
        .Where(c => c.IsBaz);
}

似乎不可能完全模拟 Include 方法,因为它返回一个 ObjectQuery,并且 Include 方法不是在任何地方的接口中捕获(没有 IObjectQuery 接口)。 ObjectQuery 实现了 IQueryable,因此我认为制作自己的返回 IQueryable 的 Include 方法会起作用,但前提是我计划每个查询最多调用一次 Include 。

我正在使用 EF4、.NET 4、Silverlight 4 和 RIA Services RTW。

有点咆哮,我对测试不友好的 LINQ to Entities 和扩展 RIA 服务感到失望:(

I have been investigating how to decouple my DomainServices from their datasource so I can test them in unit tests. I'm starting to think fully decoupling them is not possible.

There is a decent amount of info out there, such as this question and this blog post. The blog post in particular gets you really far into mocking ObjectContext.

But my DomainServices have methods like this:

public IQueryable<Client> GetClients()
{
    return ObjectContext.Clients
        .Include("Foo")
        .Include("Bar")
        .Where(c => c.IsBaz);
}

It doesn't seem possible to fully mock the Include method, as it returns an ObjectQuery<T>, and the Include method is not captured in an interface anywhere (There is no IObjectQuery interface). ObjectQuery implements IQueryable<T>, and so I thought making my own Include method that returns IQueryable would work, but only if I plan to call Include at most once per query.

I am using EF4, .NET 4, Silverlight 4 and RIA Services RTW.

As a bit of a rant, I'm disappointed at how test unfriendly LINQ to Entities and by extension RIA Services is :(

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

半暖夏伤 2024-09-10 21:18:44

我认为你不应该在那个级别进行单元测试。我全力以赴进行单元测试,但有一个点你需要停止。

假设代码是 ClientsLinqRepository 的一部分,而 ClientsLinqRepository 又实现 IClientsLinqRepository。当您实现依赖于 IClientsLinqRepository 的代码时,您可以模拟 IClientsLinqRepository。

虽然上述内容完全有效,但 ClientsLinqRepository 是一个集成实现。非常类似于您拥有 IMessageSender 并实现了 MailSender。这里你有代码,它的主要职责是与一个单独的系统集成,对你来说这就是数据库。

基于上述场景,我建议您对该类进行一些集中集成测试。因此,在这种情况下,您确实希望访问外部系统(数据库),并确保集成代码与外部系统正常工作。它将允许您快速识别代码与数据库中的任何内容是否被破坏,而无需处理系统其余部分的复杂性(这在尝试在其他级别进行集成测试时很痛苦)。

将重点集成测试与单元测试分开,这样您就可以根据需要运行速度惊人的单元测试,并在对任何集成部分进行更改时不时运行集成测试。

I don't think you should be unit testing at that level. I'm all in for unit tests, but there is a certain point where you need to stop.

Lets say that code is part of a ClientsLinqRepository, which in turns implements IClientsLinqRepository. You mock IClientsLinqRepository, when you implement code that depends on it.

While the above is perfectly valid, ClientsLinqRepository is an integration implementation. Pretty much like if you had IMessageSender and you implemented MailSender. Here you have code that its main responsibility is integrating with a separate system, for you that's the database.

Based on the above scenario, I suggest you do some focused integration tests on that class. So in that case you do want to hit the external system (database), and make sure that integration code is working appropriately with the external system. It'll allow you to quickly identify if anything in the code vs. the database is broken without dealing with the complexity of the rest of the system (which a pain when trying to do integration tests at other levels).

Keep the focused integration tests separate from the unit tests, so you can run the amazingly fast unit tests as much as you want, and run integration test when changes are made to any of the integration pieces and every now and then.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文