TL;DR: Want to simplify unit testing in ASP.NET Core? Learn how to perform LINQ mocking to test methods without affecting your real database. Discover the steps, customization options, and practical code examples in this comprehensive guide.
LINQ (Language-Integrated Query) helps you extract data from XML documents, SQL databases, arrays, and all other third-party data sources with the same basic code patterns. This enables you to avoid writing a separate query for each database. In this blog post, we are going to see how to perform LINQ mocking in an ASP.NET Core application to perform unit testing.
Mocking is a process involved in the unit testing of applications. Here, we replace (mock) the external dependencies (e.g., data) with pseudo-dependencies to test whether the units of code function as expected.
Likewise, in LINQ mocking, we can mock the entity data used in LINQ queries. In real-time applications, if you write a unit test for the methods that access the real data from a database, even a minor problem in the database will cause a failure in the unit test. At the same time, a real-time database will take on additional load while executing the unit test.
In this blog, we explain how to mock a data collection and the selection process based on LINQ queries.
Let’s explore them!
Method to be tested
We are going to test the following method with LINQ mocking in our ASP.NET Core application. This method should return the customer ID (int) when providing the customer’s email ID as the parameter to the method.
public int GetCustomerIdBasedOnEmail(string customerEmail) { int customerId = 0; if (!string.IsNullOrEmpty(customerEmail)) { try { using (CustomerEntity context = this.CustomerEntity ?? new CustomerEntity()) { customerId = (from user in context.CustomerData where user.email == customerEmail select user.Id).FirstOrDefault(); } this.CustomerEntity = null; } catch (Exception ex) { } } return customerId; }
Procedure
Follow these steps to perform LINQ mocking in your ASP.NET Core application:
Step 1: Initialize the data
Here, we are going to check how the data has been assigned with the mocked data collection. Note the following:
- Mock a specified set of tables alone based on the need of the unit test from the entity you defined. You can skip the irrelevant tables.
- Narrow down a specified set of column values to mock based on the query. You should include only the required columns in the LINQ query in which you are going to perform unit testing.
Entity Framework Core provides support for configuring DbContextOptions. Databases define extension methods on the object that allow you to configure the database connection to be used for a context.
This context will allow you to configure table data to be mocked. Initialization of the table data will be considered as mocked data inserted into that table. Mocked data can vary based on your test cases.
Refer to the following code example.
public class MockCustomerContext<T> { /// <summary> /// Get Customer context mock object /// </summary> /// <returns>Context object</returns> public CustomerEntity GetCustomerContext() { var options = new DbContextOptionsBuilder<CustomerEntity>() .UseInMemoryDatabase(Guid.NewGuid().ToString()) .Options; var context = new CustomerEntity(options); // CustomerData => table name context.CustomerData.Add(new CustomerData { Id = 111, email = "test@gmail.com" }); context.SaveChanges(); return context; } }
Step 2: Call mocked context while creating class object
We need to get the mocked data collection to the method of the class object in which you are going to do unit testing. Also note the following:
- Make sure to have an interface which includes your method as well as the property for your entity.
- Use a parameterized constructor to get the interface object. In a real-time scenario, you should create a new direct object for the entity (direct entity object will hit the real database) when the interface object is empty. The mocked entity object will hit only from the unit testing application.
Refer to the following code example.
this.ICustomerDataAccess = Substitute.For<ICustomerDataAccess>(); this.ICustomerDataAccess.CustomerEntity = new MockCustomerContext<CustomerEntity>().GetCustomerContext(); this.CustomerDataAccess = new CustomerDataAccess(this.ICustomerDataAccess);
Step 3: Write test cases
Then, we can state the act (action to be performed) and assert (to validate the action) in the test cases to validate the LINQ query. For this, you just need to call the method in Act and Assert as mentioned in the following code example. Here is just a test of whether the object is null.
/// <summary> /// Valid Customer. /// </summary> [Test] public void GetCustomerIdBasedOnEmail_ValidCustomerEmail_ReturnCustomerId() { ////Act int customerId = this.CustomerDataAccess.GetCustomerIdBasedOnEmail("test@gmail.com"); ////Assert Assert.AreEqual(111, customerId); }
Note: You can perform as much testing based on the data you mocked from the collection as you want.
Output screenshot
Here, we used NUnit to test the cases.
GitHub Repository
For more information, refer to the LINQ Mocking in ASP.NET Core application demo.
Conclusion
In this blog post, we have learned how to perform LINQ mocking in an ASP.NET Core application to perform unit testing. Try out the steps provided in this blog and share your feedback in the comments section below.
The Syncfusion ASP.NET Core UI controls library is the only suite that you will ever need to build an application. It offers high-performance, lightweight, modular, and responsive UI controls in a single package. Use them to enhance your productivity!
In addition to the comment section below, you can also contact us through our support forums, Direct-Trac, or feedback portal. We are always happy to assist you!