简体   繁体   English

如何使用Lambda表达式进行单元测试实体框架/存储库模式

[英]How to unit test with lambda expressions Entity Framework/Repository pattern

We are trying to figure out what the point of unit testing is for basic cases as in the code below. 我们正在尝试找出基本情况下单元测试的重点,如下面的代码所示。 Does making a unit test for this beneficial ? 为此进行单元测试是否有好处? We are not trying to test the entity framework. 我们不尝试测试实体框架。 We just want to make sure the lambda expression does what it should... Our idea is that we will use DI to pass in SOMETHING that is IQueryable.. In practice it will be EF but for unit tests and will be POCO objects/collections. 我们只想确保lambda表达式可以实现它应做的事情...我们的想法是,我们将使用DI传递可查询的SOMETHING。在实践中,它将是EF,但对于单元测试,它将是POCO对象/集合。 Does this makes sense ? 这有意义吗? We are just getting started and want to master the concepts before we get beyond this basic code. 我们才刚刚起步,并且想要掌握这些概念,然后再超越基本代码。

   public class CongressRepository
{
    CongressDb_DevEntities context = new CongressDb_DevEntities();

    CongressRepository(DbContext db)
    {
        context = (CongressDb_DevEntities) db;
    }

    public IQueryable<tMember> GetAllMembers
    {
        get { return context.tMembers; }
    }

    public IQueryable<tMember> GetVotingMembers
    {
        get { return context.tMembers.Where(x => x.age > 18); }
    }
}

EF uses LINQ to Entities, but when mocking EF you'd be switching to LINQ to Objects. EF使用LINQ to Entities,但是在模拟EF时,您将切换到LINQ to Objects。 This could lead to false positives in terms of your unit tests as there are differences between LINQ to Entities and LINQ to Objects. 这可能会导致单元测试方面的误报,因为LINQ to Entities和LINQ to Objects之间存在差异。 Without integration tests, you'd only see these differences / errors in your production environment. 没有集成测试,您只会在生产环境中看到这些差异/错误。

One of the reasons for unit testing code is ensuring accuracy... 使用单元测试代码的原因之一是确保准确性。

In your example someone could not vote on their 18th birthday or any of the days between it and their 19th birthday. 在您的示例中,某人无法在其18岁生日或该年龄与19岁生日之间的任何日子投票。 I'm guessing it should really be: 我猜应该真的是:

public IQueryable<tMember> GetVotingMembers
{
    get { return context.tMembers.Where(x => x.age >= 18); }
}

Unit tests which cover a range of reasonable successful and failing values help ensure that your code does what you meant it to :-) 涵盖一系列合理的成功和失败值的单元测试有助于确保您的代码符合您的意图:-)


but what we are trying to find a why to ask is how the unit tests work. 但是我们试图找到一个为什么要问的是单元测试是如何工作的。

It can be a real pain! 真是痛苦! EF6 has just been announced and makes it easier to mock the DbContext but right now it takes a lot of setup... EF6刚刚发布,可以轻松模拟DbContext,但现在需要大量设置...

The important things is that there are differences between Linq-to-Etities and Linq-to-Objects so you do need both unit testing and integration testing. 重要的是,Linq-to-Etities和Linq-to-Objects之间存在差异,因此您确实需要单元测试和集成测试。

There are lots of blogs and SO questions related though... use FakeDbSet as a starting point for some google-fu. 尽管有很多博客和相关问题,但是...使用FakeDbSet作为一些google-fu的起点。

For unit testing an object that uses DbContext, you will have to inject it as an interface into your repository object. 为了对使用DbContext的对象进行单元测试,您必须将其作为接口注入到存储库对象中。 Follow these steps: 跟着这些步骤:

1.Create an interface that contains all DbContext properties, and derive your DbContext from it: 1.创建一个包含所有DbContext属性的接口,并从中派生DbContext:

 public interface ICongressDbContext {
    IDbSet<Member> Members { get; set; }
    // repeat for all dbsets
 }

2.Give this interface to your repository in the constructor. 2.将此接口提供给构造函数中的存储库。 This is your dependency injection: 这是您的依赖项注入:

 private ICongressDbContext context;
 public CongressRepository(ICongressDbContext context){
     this.context = context;
 }

You will want to pass an instance of the context in using a dependency injection framework like Autofac, or you can create an instance where you instantiate your object. 您将要使用Autofac之类的依赖项注入框架传递上下文的实例,或者您可以在实例化对象的地方创建实例。

3.Create a generic implementation of IDbSet: https://gist.github.com/LukeWinikates/1309447 . 3,创建IDbSet的通用实现: https ://gist.github.com/LukeWinikates/1309447。 Let's call this FakeDbContext. 我们将此称为FakeDbContext。

4.Now that you have a mockable interface, and a generic DbSet implementation, you are ready to create your mock DbContext and your mock IDbSets. 4.现在您有了一个可模拟的接口和一个通用的DbSet实现,就可以创建模拟DbContext和模拟IDbSet了。 Using Moq, this looks like: 使用Moq,它看起来像:

        var dataContext = new Mock<ICongressDbContext>();
        var members = new List<Member> { // create your test data here };
        // set up the mocked context to use your fake db set with test data
        dataContext.SetupProperty(c => c.Members, new FakeDbContext<Member>(members));

        var repository = new CongressRepository(dataContext.Object);

        // start writing your test methods here

This will test the object that uses the DbContext, not the DbContext itself. 这将测试使用DbContext的对象,而不是DbContext本身。
You will want to write integration tests that use the real DbContext in addition to the unit tests. 除了单元测试之外,您还需要编写使用实际DbContext的集成测试。 There are many methods supported on IQueryable that are not supported when accessing the database. IQueryable支持的许多方法在访问数据库时不支持。 You also want to make sure your data model is mapped correctly to the database. 您还希望确保将数据模型正确映射到数据库。

I hope this helps you to get started. 希望这可以帮助您入门。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何对使用Entity Framework的存储库模式进行单元测试? - How to unit test a repository pattern that uses Entity Framework? 如何正确地对与Entity Framework / DbContext耦合的存储库模式方法进行单元测试? - How do I properly unit test a repository-pattern method, that has coupling to Entity Framework / DbContext? 使用带有接口的存储库模式时,如何使用实体框架和 Moq 进行单元测试? - How I unit test with Entity Framework and Moq when using a repository pattern with Interface? 实体框架,存储库模式,工作单元和测试 - Entity Framework, Repository Pattern, Unit of Work and Testing 我应该如何对使用Entity Framework实现的存储库方法进行单元测试? - How should I unit test a repository method implemented with Entity Framework? 如何使用ADO.NET实体框架测试存储库模式? - How to test Repository Pattern with ADO.NET Entity Framework? 如何单元测试实体框架? - How to unit test Entity Framework? 使用Entity Framework 5和存储库模式和工作单元过滤内部集合 - Filtering inner collection with Entity Framework 5 and Repository pattern and Unit of Work 使用Unity for Work of Unit / Repository模式创建Entity Framework对象 - Creating Entity Framework objects with Unity for Unit of Work/Repository pattern 实体框架,存储库模式 - Entity Framework, Repository Pattern
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM