AspNetCore-Unit Testing

AspNetCore-Unit Testing

·

5 min read

Intro:-

Unit testing is a form of testing in which individual components are isolated from the rest of the application so their behaviour can be thoroughly validated. ASP Dot NET Core has been designed to make it easy to create unit tests, and there is support for a wide range of unit testing frameworks

Task:-

You are going to create simple ASP-dot-NET Core - unittesting app

Software Requirements:-

Ubuntu-20.04 +jit [linux-x86_64]

.NET Core- 6.0.16

.NET SDK- 6.0.408

Sqlite- 3.31.1(Optional)

Level:-

Beginner

Prerequisite:-

Knowledge of C# and text editor/visual studio code

Step 1:-

Creating the GymApp Project:-
dotnet new globaljson --sdk-version 6.0.408 --output UnitTesting/GymApp

dotnet new web --no-https --output UnitTesting/GymApp --framework net6.0

dotnet new sln -o UnitTesting

dotnet sln UnitTesting add UnitTesting/GymApp

These commands create a new project named GymApp using the web template, which contains the minimal configuration for ASP Dot NET Core applications. The project folder is contained within a solution folder also called UnitTesting.

Step 2:-

Enabling the MVC Framework:-
Add the statements to the Program.cs file
builder.Services.AddControllersWithViews();
app.MapDefaultControllerRoute();
Now Program.cs file will be :-

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
var app = builder.Build();
//app.MapGet("/", () => "Hello World!");
app.MapDefaultControllerRoute();  
app.Run();

Step 3:-

Creating the Application Components
Creating the Data Model
Create a folder called Models and created a class file called Product.cs within it:-

using System.Collections.Generic;

namespace GymApp.Models {
    public class Product {

         public string Machine_Name { get; set; } = string.Empty;
        public decimal? Machine_Price { get; set; }

        public static Product[] GetProducts() {

            Product Treadmil = new Product {
                Machine_Name = "Treadmil", Machine_Price = 275M
            };

            Product Cable_crossover_machine = new Product {
                Machine_Name = "Cable_crossover_machine", Machine_Price = 48.95M
            };

            return new Product[] { Treadmil, Cable_crossover_machine };


    }
    }


}

The Product class defines Machine_Name and Machine_Price properties, and there is a static method called GetProducts that returns a Products array.

Step 4:-

Creating the Controller
created a Controllers folder and added to it a class file called HomeController.cs

using Microsoft.AspNetCore.Mvc;
using GymApp.Models;

namespace GymApp.Controllers {
    public class HomeController : Controller {

public ViewResult Index() {
           return View(Product.GetProducts());
        }
    }
}

The Index action method tells ASP Dot NET Core to render the default view and provides it with the Product objects obtained from the static Product.GetProducts method.

Step 5:-

Creating the View
To create the view for the action method, You should add a Views/Home folder (by creating a Views folder and then adding a Home folder within it) and added a Razor View called Index.cshtml,

@using GymApp.Models
@model IEnumerable<Product>
@{ Layout = null; }

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Gym App</title>
</head>
<body>
    <ul>
        @foreach (Product p in Model ?? Enumerable.Empty<Product>()) {
            <li>Machiine_Name: @p.Machine_Name, Machine_Price: @p.Machine_Price</li>
        }
    </ul>
</body>
</html>

Run :- dotnet run

Step 6:-

Creating a Unit Test Project
The convention is to name the unit test project .Tests. Run the commands shown below in the UnitTesting folder to create the XUnit test project named GymApp.Tests, add it to the solution file, and create a reference between projects so the unit tests can be applied to the classes defined in the GymApp project.

 dotnet new xunit -o GymApp.Tests --framework net6.0
dotnet sln add GymApp.Tests
dotnet add GymApp.Tests reference GymApp

Removing the Default Test Class The project template adds a C# class file to the test project, which will confuse the results of later examples. Delete the UnitTest1.cs file from the GymApp.Tests folder. Writing and Running Unit Tests
dded a class file called ProductTests.cs to the GymApp.Tests project and used it to define the class .(The CanChangeProductPrice method contains a deliberate error)

using GymApp.Models;
using Xunit;

namespace GymApp.Tests {

    public class ProductTests {
     //test1
        [Fact]
        public void ProductName_Change() {

            // Arrange
            var p = new Product { Machine_Name = "Test", Machine_Price = 100M };

            // Act
            p.Machine_Name = "New Name";

            //Assert
            Assert.Equal("New Name", p.Machine_Name);
        }
         /test 2
        [Fact]
        public void ProductPrice_Change() {

            // Arrange
            var p = new Product { Machine_Name = "Test", Machine_Price = 100M };

            // Act
            p.Machine_Price = 200M;

            //Assert

            Assert.Equal(200M, p.Machine_Price);


        }
    }
}

There are two unit tests in the ProductTests class, each of which tests a behaviour of the Product model class from the GymApp project.
A test project can contain many classes, each of which can contain many unit tests. Conventionally, the name of the test methods describes what the test does, and the name of the class describes what is being tested. Fact attribute is applied to each method to indicate that it is a test. Within the method body, a unit test follows a pattern called arrange, act, assert (A/A/A).
Arrange refers to setting up the conditions for the test.
act refers to performing the test.
assert refers to verifying that the result was the one that was expected. The arrange and act sections of these tests are regular C# code, but the assert section is handled by xUnit. The Fact attribute and the Asset class are defined in the Xunit namespace, for which there must be a using statement in every test class.
The methods of the Assert class are static and are used to perform different kinds of comparison between the expected and actual results. Each Assert method allows different types of comparison to be made and throws an exception if the result is not what was expected. The exception is used to indicate that a test has failed.

Running Tests from the Command Line
dotnet test
Correcting the Unit Test The problem with the unit test is with the arguments to the Assert.Equal method, which compares the test result to the original Price property value rather than the value it has been changed to.
Assert.Equal(200M, p.Price); Run the tests again, and you will see they all pass

Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
[xUnit.net 00:00:05.94]     GymApp.Tests.ProductTests.ProductPrice_Change [FAIL]
  Failed GymApp.Tests.ProductTests.ProductPrice_Change [32 ms]
  Error Message:
   Assert.Equal() Failure
Expected: 100
Actual:   200
  Stack Trace:
     at GymApp.Tests.ProductTests.ProductPrice_Change() in /home/devnation/UnitTesting/GymApp.Tests/ProductTests.cs:line 32

Failed!  - Failed:     1, Passed:     1, Skipped:     0, Total:     2, Duration: 24 ms - /home/devnation/UnitTesting/GymApp.Tests/bin/Debug/net6.0/GymApp.Tests.dll (net6.0)


Starting test execution, please wait...
A total of 1 test files matched the specified pattern.

Passed!  - Failed:     0, Passed:     2, Skipped:     0, Total:     2, Duration: 13 ms - /home/devnation/UnitTesting/GymApp.Tests/bin/Debug/net6.0/GymApp.Tests.dll (net6.0)

Conclusion:-

After performing above steps, you made a base ASP-dot-NET Core -UnitTesting basic app. Also in this tutorial you have explored about unit testing.You have learned how to create the xUnit project and how to use [Fact], A/A/Aattributes. Also, you have created two tests to test your logic in the ProductTests class.