ASP. WEBAPI + EF Unit Test architecture DbContext one stop.

Source: Internet
Author: User

In fact, I've written about WEBAPI and EF Service unit tests before, and you can refer to:

ASP. NET WebAPI Unit test

Unit test mock EF dbcontext and Dbset Include

Let's take a look at the project structure diagram:

This demo is very simple, utwebapi.data is a pure data definition, Utwebapi.service is our business service logic layer, UTWEBAPI is our WEBAPI implementation, Utwebapi.tests is the test project.

Data layer:

Bloggerdbcontext's constructors are generally one, and sometimes there are several, such as:

If your dbcontext contains all the tables in the database, then as long as the first constructor is available, but if your table is in a few dbcontext, then the second constructor may be needed, for example, if you need to manipulate 10 tables simultaneously, then these 10 tables should be in the same transaction. , but they are distributed in 2 DbContext, so these 2 dbcontext should be connected with one.

The configuration class for the internal class articleconfiguration:entitytypeconfiguration<article> entity should not be public.

Service Layer:

We first need a base class service as follows

Of course many project development time likes to use the repository mode, I also here is simple realization as follows:

and our specific service implementation is very simple. Public Articleservice (Bloggerdbcontext ctx): Base (CTX) {}

WEBAPI Layer:

In the ASP. NET WebAPI unit test, the WebAPI IOC uses the UNITY.WEBAPI corresponding test is autofac.webapi2, This time we switched to StructureMap (today in the company trying to webapi inside with unity, found that its service was also used in unity, But previously used is 2.1, now UNITY.WEBAPI use is 5.1, so to use unity also to change the previous service layer code, and then use StructureMap). There are 2 help classes to develop:

     Public classStructuremapscope:idependencyscope {Private ReadOnlyIContainer container;  Publicstructuremapscope (IContainer container) {if(Container = =NULL)            {                Throw NewArgumentNullException ("Container"); }             This. Container =container; }         Public ObjectGetService (Type servicetype) {if(ServiceType = =NULL)            {                return NULL; }            if(Servicetype.isabstract | |servicetype.isinterface) {return  This. Container.            Trygetinstance (servicetype); }            return  This. Container.        GetInstance (servicetype); }         Publicienumerable<Object>getservices (Type servicetype) {return  This. Container. Getallinstances (servicetype). cast<Object>(); }         Public voidDispose () { This. Container.        Dispose (); }    }     Public classStructuremapdependencyresolver:structuremapscope, Idependencyresolver {Private ReadOnlyIContainer container;  Publicstructuremapdependencyresolver (IContainer container):Base(container) { This. Container =container; }         PublicIdependencyscope BeginScope () {varChildcontainer = This. Container.            Getnestedcontainer (); return NewStructuremapscope (Childcontainer); }    }
View Code

The specific use is as follows:

API Run Results

Test Project:

First Test requires mock DBContext, you can refer to the unit test mock EF DBContext and Dbset Include to do, second we need a dbhelper, use it to the goods DBContext and initialize the data:

Then the code for the test project is very simple:

See here the test has passed, this dbcontext is common to all the tests, just like our database, especially the DbContext table is more (more than 500), then the mock this dbcontext takes a relatively long time.

The structure of the whole project is finished, generally our controller's IOC is to do the service layer, and the service layer needs the IOC data layer, just like the ASP. NET WebAPI unit test in front of me Getiarticleservice method, its implementation is still relatively tired, Too many mock-up,

At the same time in the controller there is more than the IOC code, each additional controller needs to add a corresponding service, then the IOC corresponding configuration also to increase is not very troublesome? So simply direct IOC DbContext. Because code reuse is not very high in many of our actual projects, when adding controllers, it is generally necessary to increase the service to implement the corresponding logic, such as a query logic now has 3 service has been implemented, But in controller you may not use these 3 service directly, but instead build a service, Merge 3 EF queries into one, so that EF accesses 3 times the DB becomes once, and the unwanted data is not returned. So here the DbContext really is a stop, from the data layer through the service layer finally adhere to the interface layer, and the difficulty of unit testing in how to mock DbContext, here we use pierced return to the way to do (expression to DbContext dbset assignment).

ASP. WEBAPI + EF Unit Test architecture DbContext one stop.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.