I need to write unit testing for legacy code. I'm using MoQ for wring DB Context based unit testing. One repository method contains saving 2 entities in a transaction.
And when the test execution hit the dbContext.Database.BeginTransaction() it gives the error "No connection string named 'LimaV3DbContext' could be found in the application config file".
It seems the test trying the execute the actual db context rather than using the mock db context. Is there a way to force the test execution to use the mock db context used in the test initialization.
I've setup the tests based on the following article.
https://learn.microsoft.com/en-us/ef/ef6/fundamentals/testing/mocking
public ApplicationLayout Get(string objectName, string userName)
{
using (var db = new SqlConnection(_connectionString))
{
var sql = "SELECT * FROM dbo.ApplicationLayout WHERE ObjectName = #ObjectName AND UserName=#UserName";
return db.Query<ApplicationLayout>(sql, new {ObjectName = objectName, UserName = userName}).FirstOrDefault();
}
}
I have some code here, and I was wondering if it is possible to perform a unit test in C# using SQL data (any framework). From what I've seen, it is not possible. Can anyone please confirm this?
I always did my testing on a dedicated database. You can do a setup and a tear down, and basically recreate the database (or restore it from a backup) each time you run those tests. It is a lot more involved than just plain C# unit testing. Like some comments stated, it's not really unit testing anymore but stuff needs to be tested one way or another.
Possible, but not recommended for a unit test.
When you talk about a unit test, you're usually talking about a test that can be repeatably executed in isolation; that is, it has no dependencies outside the code assembly where it lives (and ideally each test should not go very far beyond a single class being tested), and has no lasting side effects regardless of how the test is started or stopped (doesn't require use of the file system, or a database, etc). This is because unit tests, being the smallest and most fine-grained tests, are intended to test the code that you yourself wrote. You didn't write SQL Server, so SQL Server shouldn't be in the scope of a unit test.
Now, once you widen the scope to integration tests and acceptance tests, now you're testing that code you wrote plays nicely with all the external dependencies you didn't write. Integration tests can touch external data, like databases, and can write to as well as read from those external stores, as long as they clean up after themselves properly, either by returning a persistent database to its original condition after the run, or just using a portable DB like SQLite or MSS Express, setting up the necessary schema and test data as part of your test setup, and then just blowing the DB away when it's done.
For many, this is splitting hairs, and unit testing frameworks like MSTest or NUnit don't prevent you using them to create a test that has external dependencies. These are merely good ideas for structuring your full test suite into a fine-grained, fast-running, repeatable component that you can run on any change you make, and the longer-running, wider-scoped proof of correctness that might run overnight.
The modern approach to orchestrate testing against a real SQL engine has to work:
locally on dev machines (that run Windows, MacOS or Linux);
build pipelines in the cloud (e.g. Azure DevOps pipelines, GitHub Actions,
etc.).
TL;DR – check out DbSample on GitHub, a sample EF Core based
project with fully automated tests against MS SQL Server and a GitHub
Actions pipeline.
A detailed analysis of orchestrating tests is covered in "Pain & Gain of automated tests against SQL (MS SQL, PostgreSQL)" article. The key steps are:
Launch SQL engine in Docker (use official images for SQL Server or PostgreSQL)
Create a test database and populate the schema, logic, lookup dictionaries, etc (via command line for the containers)
Connect xUnit/NUnit tests to the database and for each test (rinse and repeat):
Seed test data
Perform the testable activity and checks
Revert the database to the pristine state (via Respawn)
Tear down the SQL engine along with the database and other artefacts.
P.S. I know, the OP said "unit tests" but perhaps meant a more broad "automated tests"
I am developing an ERP that is not based on EF. My question is: how can I do perform test using AutoFixture for all the CRUD without using doing mocking? How can I perform cleanup and Setup operation for Unit Test.
Likewise, I need to test update and delete operation alone with insert. What I have seen on different site there are only insert fixture examples without using mock.
I have a problem running data driven unit tests (MSTest) in VSTS. My situation is the following:
In my C# solution I have a MSTest-test project which contains three test classes that contain data driven test methods.
These methods used to work with an attached MDF-file as data source, but for reasons of maintainability I added a database-project to my solution which contains the scripts to create and fill a database with my test data.
The test-project also contains an initialize method (marked with the AssemblyInitialize attribute) which deploys the dacpac from the database-project) to a LocalDB-instance. For this deployment I use the Microsoft.SqlServer.DACFx NuGet-package.
The data driven test methods all use the following connection string
Data Source=(LocalDB)\v11.0;Initial Catalog=Enkoni_Validation_Tests;Integrated Security=True;Connect Timeout=30
The problem is that this solution workes locally without any problems, but when I trigger a build on VSTS, most of the tests run fine, but one test class constantly failes with the message
"The unit test adapter failed to connect to the data source or to read the data. (...) Error details: Cannot open database "Enkoni_Validation_Tests" requested by the login. The login failed."
The testmethods in the other two classes run without any problems. Since all three test classes are part of the same project, I assume the initialization (the deployment of the DacPac) runs without problems.
Has anyone experienced a similar problem or does anyone know how to solve this?
Edit (added some additional information): the build runs on a hosted build agent and it's always the same test that fails. I have considered that maybe there is some sort of limitation on how many connections can be made to the LocalDB database, but I can't find any information that supports this theory. And since all my tests run sequential, I also don't expect that there are many (or even more than one) connections.
When running c# integration tests, I'm trying to recreate my table in a transaction scope for each test, though I'm getting the following error:
DROP DATABASE statement cannot be used inside a user transaction.
What does it mean? How do I handle it?