在单元测试中使用Entity Framework是一种好习惯吗?

时间:2010-01-18 14:35:55

标签: .net unit-testing entity-framework

我正在为服务编写 NUnit 测试。

我决定通过向数据库发送直接 SQL语句而不是使用实体框架模型来实现此目的,以便我可以确定缓存结果等)

唯一的缺点是使用SqlCommand,SqlDataReader等编写此代码是乏味,并且能够使用 EF模型会非常强大>更容易

其他人如何做到这一点?在编写测试时使用Entity Framework或使用直接调用数据库来确保准确的结果是不错的做法?

5 个答案:

答案 0 :(得分:1)

我认为在测试服务时这是一种不好的做法,因为它会对数据库产生依赖性。

我所做的是将我的Model类汇总到Repository模式中。存储库模式已编码为接口,以便我可以更改数据库查询的实现,而不会影响代码的其他部分。它可以很容易地模拟并用于测试。这是我构建的界面。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace App.Core.Repositories
{
    public interface IRepository<TKey, TModel>
        where TKey : IComparable
        where TModel : class
    {
        TModel Only(TKey key);
        IQueryable<TModel> Where(Func<TModel, bool> query);

        TModel Single(Func<TModel, bool> query);
        TModel First(Func<TModel, bool> query);
        IQueryable<TModel> All();

        void Insert(TModel entity);
        void Insert(IEnumerable<TModel> entities);

        void Update(TModel entity);
        void Update(IEnumerable<TModel> entities);

        void Remove(TModel entities);
        void Remove(Func<TModel, bool> query);
        void Remove(IEnumerable<TModel> entities);
    }

    public interface IRepository<TModel> : IRepository<int, TModel> where TModel : class { }

    public interface IRepository : IRepository<int, object> { }
}

答案 1 :(得分:1)

恰恰相反。我们DA层的测试根本不关心数据库。

例如。我们有一个调用Save方法来保存新数据对象的测试。然后,它调用Load方法来检查是否可以加载对象。我不关心对象实际上是否保存到数据库的天气,我关心的是我可以检索已保存的对象。如果EF想要做一些聪明的缓存而不立即保存,那么我就没事了。

考虑到将来我们可能不再使用SQL服务器后端,我们可能会切换到oracle,甚至是NOSQL解决方案。当我切换后端时,我不希望所有DA层单元测试都中断。实际上反过来,我需要我的DA层单元测试继续工作不变,这样我就可以验证存储解决方案的切换不会影响语义或使用DA层。

答案 2 :(得分:1)

好吧,让我们这样说吧:你不应该编写单元测试来确保实体框架本身有效。这是微软的工作。

另外,有些人认为在“单元测试”中获取SQL Server数据库完全意味着您现在正在进行集成测试而不是单元测试。这,不管你怎么做。不过,我不打算这么说。

您编写的单元测试应该测试您自己的代码。

您说直接读取数据库的原因之一是您的应用程序可能会看到缓存数据。谁写了那个缓存?如果是你,那么一定要对它进行单元测试,尽管在这种情况下我可能会模拟数据库访问。

但如果它是SQL Server(或实体框架)的缓存,你会担心,嗯,你会从哪里开始?这些产品非常庞大,您无法对整个系统进行单元测试。

这并不意味着您应该假设SQL Server和实体框架没有缺陷。但是,通常通过集成测试应用程序而不是单元测试来捕获框架中的错误。

答案 3 :(得分:0)

我们在单元测试中使用 LINQ to SQL 代替使用LINQ to Entities,因为它更接近数据库架构。

然而,我们已经厌倦了保持自动生成的L2S代码与实际数据库同步,而不是厌倦了做所有的SqlCommand等等......

答案 4 :(得分:0)

正如Craig和其他人已经指出的那样:你正在进行集成测试。

这意味着我必须以“否”回答您的主要问题。

但是,对于集成测试,您可能通过使用位于另一个appdomain中的EF上下文来绕过任何内存中缓存。每个appdomain都会看到自己的一组静态值,所以即使EF在版本5中使用静态缓存(我怀疑),你也可以用db-agnostic方式测试它。 (对您的软件支持的所有后端重复这些测试。)

这是偏执狂版,顺便说一下。第二个背景应该已经成功了。