Listen to the blog...

This blog post is aimed at developers with at least a small amount of unit testing experience. If you’ve never written a unit test, please learn the basics of unit testing and then continue with this blog.

The key to Unit Testing is that each piece of code needs to be tested with a set of tests to validate each individual method’s expected functionality. There are few common issues which the developers face while unit testing their code.

While working on unit tests, developers meet with some problems which are most probable to occur in Unit Testing scenario. So, this blog is going to explain the problems and their solutions.

1. Testing Model Validation:

The ModelState is validated by the model binding which happens in OnActionExecuted filter not when you call the action. Due to this reason we have to validate model state explicitly. For this purpose we will use TryValidateObject() function of Validator class.

The model validation is tested by comparing the actual and expected errors messages in an Assert. We can access the error messages associated with each property of model and compare these messages with the actually arising errors while validating the model.

Following figure shows an example of it:

unit-testing-1

2. Running all tests together causes Sequence problem:

The test methods easily get executed according to their expected behaviour on individual run. But while running all tests together some of them gives results as opposed to their expected behaviour i.e. the tests which are expected to be passed are being failed. This problem occur because the method is getting the data which is modified by some other test method

To resolve this problem there are two possible solutions:

• First one is to use Ordered Tests. In this way we can specify sequence of each test in which they should execute so that expected data is provided to the methods.

• Second one is to provide separate data for each method so that the execution of a test method does not affect the execution of other test methods. For example, if we have two test methods which are updating the data in database so we should provide both this methods different set of data.

3. Handling the non-testable code:

There are two modes to execute a code: Debug and Release. While unit testing there may be some piece of code which cannot be tested or we do not want to test i.e. code for sending mails. This type of code can be omitted by using the DEBUG pre-processor and enclosing the non testable code in an if statements as shown in the following figure:

unit-testing-2

This code will be skipped while testing the action.

4. Testing Routes:
The browser is not available while testing so we cannot generate URL. To generate URL we use the Mock of HttpContextBase class as follows:

unit-testing-3

5. How to Test Asynchronous Actions:

The asynchronous actions have “Task” return type. For unit testing such methods our unit test methods should also have the return type “Task”

The following sample code contains an asynchronous action:

unit-testing-4

We will specify the return type of our test method as Task and use the await keyword while calling the action. Following is the corresponding test method:

unit-testing-5

6. Issue With UserId of Identity Framework :

ASP.NET Identity is the new membership system for building ASP.NET web applications. ASP.NET Identity allows you to add login features to your application and makes it easy to customize data about the logged in user. While unit testing some piece of code in our method under test is accessing the identity information. So in order to set the user in our test method context set the claim, identity and principal properties for a user and pass it to the controller as follows:

unit-testing-6

The above code will evaluate the result for “User.Identity.GetUserId()”

7. How to set Initial values for static variables:
Create a TestCleanup method in your test class and set the desired values for static variables in it. These variables can be accessed as “ControllerName.StaticVariableName“. The cleanup method will be run after each test method and set the initial values for the static variables

unit-testing-7

8. “Refresh object state Manager Entry” Exception:
The way Entity Framework works is that it watches the entire collection it has last been read, since the data is being saved and no re-reading on it is performed, its having difficulty with change tracking and state that’s why when we run all the tests together then this exception may occur while updating data.
As a solution we have to manually update the state of object manager using the following code:

unit-testing-8

9. “DataReader must be Closed” Exception:

When we retrieve an entity from the database which is having navigation properties then there are multiple data retrieval commands executed on a single connection while next DataReader is executed before first one has completed the reading or during an execution we trigger Lazy Loading for loaded entity then this exception may occur.
To prevent this we will turn on multiple DataReaders for this we will specify “MultipleActiveResultSet= true” in the connection string.

So, this blog post covers many problems related to ASP.NET unit testing and “to the point” solutions are also provided to make the unit testing work easy. Hope this will help you.

Subhashini Barthwal| SunArc Technologies
Subhashini Barthwal
Google Certified | Head – Digital Marketing & Analytics at SunArc Technologies| MarTech Engineer | White Hat SEO Expert