📜 ⬆️ ⬇️

We test EntityFramework queries using SQL Server Compact Edition

Like all serious people, we are thinking about the widespread use of unit tests. We took MSpec as a platform because some team members really like the fact that test names look like you read the text, but unlike cucumber and others like it, you don’t have to write bulky parsers.

Unit testing and moki - this is certainly good and necessary, but sometimes you want to check that the piece of code that works with the base works correctly in the whole. Yes, and I want to install the stop in the right place and go there without launching all the heavy applications. In general, there was a desire to test the base.

First decided to try SQLite. Small, theoretically a lot of things who can, in general, everyone is familiar with him. Which was zapinat as the first option, but after butting so that the provider for SQLite does not create EntityFramework requests for SQLite as for the SQL server, it was decided to look closer to the roots for Microsoft. Fortunately, as always in the world of .NET, there is not a lot of choice of implementations, but they are sufficiently ridiculous. In general, it was decided to start SQL Server CE.

Immediately arises complexity. We want the Edmx file under MSSQL and so that there are no references to SQL CE in it. We solve this question simply and valiantly. Add to the project with tests t4 template (.tt) which produces some necessary manipulations with the description of the scheme.
')
To begin with, put Nuget packages into your usual hand.
Install-Package SqlServerCompact Install-Package EntityFramework.SqlServerCompact 


Next, we take out the edmx SSDL and replace the Provider with SQL CE in it, and bring the types from SQL Server specific to SQL CE into a subset.
 ... <# var di = new DirectoryInfo(Host.ResolvePath("..\\DataAccessLayer\\")).FullName; var xmlDocument = new XmlDocument(); xmlDocument.Load(Path.Combine(di,"Entities.edmx")); var xmlNamespaceManager = new XmlNamespaceManager(xmlDocument.NameTable); xmlNamespaceManager.AddNamespace("edmx", "http://schemas.microsoft.com/ado/2009/11/edmx"); xmlNamespaceManager.AddNamespace("ssdl", "http://schemas.microsoft.com/ado/2009/11/edm/ssdl"); //  SSDL  EDMX var selectSingleNode = xmlDocument.SelectSingleNode("//ssdl:Schema[@Namespace='___']", xmlNamespaceManager); //  Provider ((XmlElement) selectSingleNode).SetAttribute("Provider", "System.Data.SqlServerCe.4.0"); //   //  foreach (XmlElement node in xmlDocument.SelectNodes("//ssdl:Property[@Type='varbinary(max)']", xmlNamespaceManager)) { node.SetAttribute("Type","image"); } #> 


After that we get a specially prepared ssdl, which we want to feed our context.
First we make it a resource - in the properties of the object and just in case, in the project, you can write a more sane than the standard name tag LogicalName
  <EmbeddedResource Include="SqlCompact.ssdl"> <AutoGen>True</AutoGen> <DesignTime>True</DesignTime> <DependentUpon>SqlCompact.tt</DependentUpon> <LogicalName>SqlCompact.ssdl</LogicalName> </EmbeddedResource> 

In the templates created by EF for the context, we made the default constructor private, and the public constructor that was added always requires the IConnectionString parameter, whose implementations deal with the output of the ConnectionString for everyone. In the project code, this interface is mapped to issue a standard implementation. For tests, the IConnectionString implementation must return the provider as System.Data.SqlServerCe.4.0 and Persist Security Info = True - otherwise it will not take off. In addition, in connectionString it is necessary to replace the original ssdl with the one generated and compiled into the resource above.

We start writing tests for which we create the base of entities.Database.Create () and are happy to test a bit more than before.

Total:
1) Put the packages
2) We take a bite SSDL with t4 and change the types in it
3) Change the provider in the SSDL and in the connectionstring (if nuget is buggy, then in App.config)

If you still want SQLite, then the algorithm is similar, but you will have to create tables yourself because of the clumsy implementation of the autoincrement type in it and you can forget about foreign keys.

Source: https://habr.com/ru/post/202674/


All Articles