Skip to content
  • iImagine
  • Register
  • Log In

Web Development School

Learning made easy.

  • Books
    • Beginning Web Development with ASP.Net Core & Client-Side Technologies
      • TOC
      • Part 1
        • Chapter 1: Static HTML – Designing the landing page
      • Part 2
        • Chapter 2: ASP.Net Core – Let’s talk Dynamic
        • Chapter 3: Introduction to ASP.Net Core MVC
          [ASP.Net Core v9]
      • Part 4
        • Chapter 7: Using Server Side & Client Side technologies together
          [ASP.Net Core v7 & Angular 15]
  • Environment Setup
    • Installing Angular
    • Installing Visual Studio 2022
    • Installing SQL Server 2022 Express
    • Installing Postman
    • Installing Git for Windows
  • Blog
  • iImagine WebSolutions
  • Events
  • Learning Videos
  • Toggle search form

Unit Test 1: Home Controller Can Use Vehicle Repository

Up to this point we have spent a lot of time building up the infrastructure and setting up our project as an MVC application. Along the way we have talked a lot about popular MVC patterns such as DI (Dependency Injection) and the Repository pattern.

After all of this work we have only just created our first feature; displaying a list of vehicles to the user. But once all of this initial work is done, features we build going forward should snap more quickly into place.

One of the biggest benefits of an MVC application is it’s testability. In this module we are going to create our first unit test. We need to test that the controller can access a list of vehicles through the repository.

Table Of Contents
  1. Create the Unit Test project
    • Create the xUnit project
      • What are unit tests?
      • Other Testing Frameworks.
    • Add the Test Project to the Solution
    • Add a reference to the main project
      • Delete the default unit test
  2. Add the Moq package to the Test project
  3. Write the Unit Test: First Draft
    • Run the Unit Test: First Draft
      • Test Explorer
  4. Write the Unit Test: Second Draft
    • Add the MockQueryable.Moq package
    • Modify the test code
    • Inspect the test code
      • AAA (Arrange-Act-Assert) pattern in unit testing
        • Arrange Section
          • Create the test data
          • Mock the IQueryable using MockQueryable package
          • Build the mock IVehicleRepositoy
          • Instantiate the HomeController
        • Act Section
        • Assert Section
        • Assert methods
          • Equality Assertions
          • Boolean Assertions
          • Null Assertions
  5. What's Next

Create the Unit Test project

The first thing we need to do is create the unit test project, add it to the solution, and make a reference from the unit test project to the main FredsCars project.

Create the xUnit project

In this chapter we are going to use the xUnit testing framework.

xUnit is a popular unit testing framework for .NET applications. xUnit provides a simple way to write and execute unit tests. xUnit is widely used in the .NET ecosystem and is the preferred testing framework for modern .NET applications.

What are unit tests?

Unit tests in ASP.NET Core MVC are automated tests that validate the functionality of individual components (such as controllers, services, and repository classes) in isolation. The goal of unit testing is to ensure that each unit of the application works as expected independently, without relying on external dependencies like databases, file systems, or APIs.

Other Testing Frameworks.

There are several testing frameworks available to use. Throughout the years I have used MSTest and NUnit. But xUnit is now the preferred unit test framework for .Net Core.


Open up a command window and use the dotnet new command to create an xUnit project in the FresCars solution folder; the folder that contains the FredsCars.sln file.

 dotnet new xunit -n FredsCars.Tests --framework net9.0

Once the command finishes running, there should be a FredsCars.Tests folder next to the FredsCars project and the solution file in the solution folder.

Add the Test Project to the Solution

Run the command below in the solution folder.

dotnet sln FredsCars.sln add FredsCars.Tests

Once the command finishes the output will show that the test project has been added to the solution.

In Visual Studio there will be a popup message saying that the solution file has been modified outside of the environment. Click the Reload button.

Now the FredsCars.Tests project should show up in Solution Explorer.

Add a reference to the main project

Run the command below in the solution folder.

dotnet add FredsCars.Tests reference FredsCars

Once the command finishes, the output will show that a reference to the FredCars project has been added to the test project.

You can see the reference was added in Solution Explorer by expanding the Dependencies folder in the FredsCars.Tests project and from there expanding Projects.

Delete the default unit test

When you create an xUnit project, there is a default test file called UnitTest1.cs. You can delete that now.

Add the Moq package to the Test project

The unit test we are going to write is for the Home Controller. But as stated earlier, we want to make sure any error we get is actually from the controller itself and not from the repository service. The repository service is said to be a dependency of the Home Controller because it is declared as an incoming parameter of the Home Controller’s constructor method.

public HomeController(IVehicleRepository repo)
{
    _repo = repo;
}

In order to make sure the repo (or the dependency) is not the cause of any potential error, we need to be able to control it’s behavior, in this case the data (or test data) that it returns. So, we need to fake, or mock, the repository.

We are going to use the Moq package to mock the vehicle repository so the next thing we need to do is install the package. In a command window run the following command in the FredsCars.Tests project folder; the folder with the FredsCars.Tests.csproj file.

dotnet add package Moq --version 4.20.72

NOTE: version 4.20.72 is the latest version at the time of this writing. Remember to always check back in Nuget.org for the latest version.

Once the command finishes running, you can verify the package was installed in Solution Explorer by expanding the Packages node.

Write the Unit Test: First Draft

A lot of books and tutorials I read put all of the unit tests on the root of the test project. To me it seems you would end up with a huge number of disorganized tests you have to dig through to find what test you are looking for when you need it. I like to try to organize my tests with the same folder structure of the project I am testing. So, create a folder called Controllers in the root of the test project. Then add a class file in the Controllers folder called HomeControllerTests_Fails.cs.


I want to take you through the process of writing a unit test for the Index method of the Home Controller. But because the Index method is asynchronous, there are a few extra steps we need to perform to get the test to succeed.

First we are going to write a test that fails, inspect the error, and then apply the fixes.
So, in the new Controllers folder create a file called HomeControllerTests_Fails.

Modify the HomeControllerTests_Fails.cs file with the code below.

FredsCars.Tests\Controllers\HomeControllerTests_Fails.cs

using FredsCars.Controllers;
using FredsCars.Models;
using FredsCars.Models.Repositories;
using Moq;

namespace FredsCars.Tests.Controllers
{
    public class HomeControllerTests_Fails
    {
        [Fact]
        public async Task Can_Access_VehicleList_FromVehicleRepo()
        {
            // Arrange
            Mock<IVehicleRepository> mockVehicleRepo =
                new Mock<IVehicleRepository>();
            mockVehicleRepo.Setup(mvr => mvr.Vehicles).Returns((new Vehicle[]
                {
                    new Vehicle
                    {
                        Id = 1,
                        Make = "Make1",
                        Model = "Model1",
                        VehicleType = new VehicleType
                        {
                            Id = 1,
                            Name = "Car"
                        },
                    },
                    new Vehicle
                    {
                        Id = 2,
                        Make = "Make2",
                        Model = "Model2",
                        VehicleType = new VehicleType
                        {
                            Id = 1,
                            Name = "Car"
                        },
                    },
                    new Vehicle
                    {
                        Id = 3,
                        Make = "Make3",
                        Model = "Model3",
                        VehicleType = new VehicleType
                        {
                            Id = 2,
                            Name = "Truck"
                        },
                    },
                    new Vehicle
                    {
                        Id = 4,
                        Make = "Make4",
                        Model = "Model4",
                        VehicleType = new VehicleType
                        {
                            Id = 3,
                            Name = "Jeep"
                        },
                    }
                }
            ).AsQueryable<Vehicle>());

            HomeController controller = new HomeController(mockVehicleRepo.Object);

            // Act
            IEnumerable<Vehicle>? result =  
                (await controller.Index()).ViewData.Model
                    as IEnumerable<Vehicle>;

            // Assert
            Vehicle[] vehicleArray = result?.ToArray()
                ?? Array.Empty<Vehicle>();
            Assert.True(vehicleArray.Length == 4);
            int carCount = vehicleArray.Where(v => v.VehicleType.Name == "Car").Count();
            Assert.Equal(2, carCount);
            Assert.True(vehicleArray[3].Make == "Make3" &&
                vehicleArray[3].Model == "Model3");
            Assert.True(vehicleArray[4].Make == "Make4" &&
                vehicleArray[3].Model == "Model4");
        }
    }
}

Run the Unit Test: First Draft

Test Explorer

To run the unit test we can use Visual Studio’s built in Test Explorer.

Open the Test Explorer by selecting Test -> Test Explorer from the top menu in Visual Studio. The window will open in the right panel of Visual Studio in a tab next to Solution Explorer.

As you can see it discovers the first test called Can_Access_VehicleList_FromVehicleRepo under the HomeControllerTests_Fails.cs node representing the class the unit test is written in.

When a test fails the error messages can be quite lengthy so feel free to undock the Test Explorer to make it bigger.


To run the test right click on the Can_Access_VehicleList_FromVehicleRepo test node in Test Explorer and select the Run option in the context menu with the green arrow icon.

When a test fails it will show a red circle with an x in the center to its left. When it passes there will be a green circle with a checkmark in its center. Here we can see that the test failed.

In the Test Detail Summary pane of the Test Explorer it shows there was a System.InvalidCastException.
The error reads,

"Unable to cast object of type 'System.Linq.EnumerableQuery1[FredsCars.Models.Vehicle]'
to type
'System.Collections.Generic.IAsyncEnumerable1[FredsCars.Models.Vehicle]'.

We also see in the stack trace that the error happens at line 19 in the Index method of the Home Controller which was called by our unit test at line 68.

What the error message is saying is that the Index method is trying to convert a type of EnumerableQuery from the System.Linq namespace to a type of IAsyncEnumerable in the System.Collections.Generic namespace.

This is a hard error to track down because the method runs fine without error at run time and there are no errors (red squiggles) in the HomeControllerTests_Fails.cs file at compile time or while we are writing the code.


The error happens in the Index method of the controller when we try to call the Vehicles property in the repository asynchronously using the ToListAsync method.

public async Task<ViewResult> Index()
{
    return View(await _repo.Vehicles
        .Include(v => v.VehicleType)
        .ToListAsync());
}

This runs fine at run time when the IVehicleRepository is implemented with the EFVehicleRepository.

public IQueryable<Vehicle> Vehicles => _context.Vehicles;

Here, the Vehicles property returns the Vehicles DbSet from the DbContext. And, as we have already noted a DbSet inherits from an IQueryable so it easily maps to the IQueryable return type of the repo Vehicles property.

But for the unit test we had to mock the Vehicle repository.

To do this, in the Can_Access_VehicleList_FromVehicleRepo unit test method of the HomeControllerTests_Fails.cs class file, we start off by instantiating an instance of a mocked IVehicleRespository using the Moq package we installed earlier.

Mock<IVehicleRepository> mockVehicleRepo =
    new Mock<IVehicleRepository>();

Next, we have to specify what the Vehicles property of our mocked IVehicleRepository will return. And, remember, it has to be of type IQueryable<Vehicle>.

So, as shown below we use the Setup method to specify which property (or method) of the mocked repo we want to specify behavior for, in this case Vehicles. Next, we specify what the Vehicles property should return using the Returns method.

FredsCars.Tests\Controllers\HomeControllerTests_Fails.cs

... existing code ...
mockVehicleRepo.Setup(mvr => mvr.Vehicles).Returns((new Vehicle[]
    {
        new Vehicle
        {
            Id = 1,
            Make = "Make1",
            Model = "Model1",
            VehicleType = new VehicleType
            {
                Id = 1,
                Name = "Car"
            },
        },
        new Vehicle
        {
            Id = 2,
            Make = "Make2",
            Model = "Model2",
            VehicleType = new VehicleType
            {
                Id = 1,
                Name = "Car"
            },
        },
        ... rest of vehicles ...
    }
).AsQueryable<Vehicle>());
... existing code ...

In the code above we specify an array of Vehicles to be returned by the Returns method and at the end we convert it to an IQueryable<Vehicle> with the AsQueryable<Vehicle> method. This conversion is what would lead us to believe our repo is fine. Our mock repo should behave just like our runtime repo.

In the next line of the unit test we instantiate an instance of the HomeController and inject our mock repo into its constructor using the mock’s Object property.

HomeController controller = new HomeController(mockVehicleRepo.Object);

And finally, in the next line is where the error happens.

IEnumerable<Vehicle>? result =  
    (await controller.Index()).ViewData.Model
        as IEnumerable<Vehicle>;

In the code above, we try to call the controller’s asynchronous Index method using the await keyword.

To see the resulting error by this call, set a breakpoint right after the return statement in the HomeController’s Index method by clicking in the left gray gutter.

Next, debug the unit test by right clicking on the unit test and selecting the run option in Test Explorer.

And we can see our infamous error with the same error message we looked at earlier.

It turns out there is just something about the nature of mocking an object to return an IQueryable and trying to access those results asynchronously that can be an awkward process.

Write the Unit Test: Second Draft

In the last section we took a good shot at writing our unit test but got a red failing result. But that’s ok. As a matter of fact fact, this is perfectly normal. Usually this iterative process can help us discover bugs or bad coding logic in our code. In this case the cause of the error is a little different. We need to deal with the awkwardness of testing a mocked IQueryable result asyncronously.

Add the MockQueryable.Moq package

Luckily for us the Moq package has an extension to deal with this situation in a separate package called MockQueryable.Moq.

If you search for MockQueryable.Moq in Nuget.org and go to README tab it states:

Extensions for mocking Entity Framework Core (EFCore) operations such [as] ToListAsync, FirstOrDefaultAsync etc. by Moq, NSubstitute or FakeItEasy When writing tests for your application it is often desirable to avoid hitting the database. The extensions allow you to achieve this by creating a context – with behavior defined by your tests – that makes use of in-memory data.

The main point to take away here is that the Moq extensions in this package will help solve our problem of setting up a test to return an IQueryble from a mocked repository via the ToListAsync method.

Let’s install the MockQueryable.Moq package now. Open up a command window, point it to the FredsCarsTests project, and run the command below.

dotnet add package MockQueryable.Moq --version 7.0.3

Once the command completes, we can see that the Moq extensions package has been installed through Visual Studio.

Modify the test code

Create a new test class in the controllers folder of the FredsCarsTests project called HomeControllerTests.cs and modify it with the code shown below.

NOTE: Normally we would not create a file called HomeControllerTests_Fails.cs to put failing unit test code in a separate file. We would create the HomeControllerTests.cs file, write the original unit test code there, and watch it fail. Then correct the errors, refactor the code, and watch it fail until after as many iterations as needed until we get a green passing result. But I wanted you to be able to look at and compare the two versions because the first version is a standard unit testing setup you will see in many books and tutorials. So I wanted to take you through that process, watch it fail, create a working version, and be able to refer back and forth as well as completely understand why this standard setup would not work for us once we implemented asynchronous code in the Home Controllers Index method.

FredsCars\FredsCars.Tests\Controllers\HomeControllerTests.cs

using FredsCars.Controllers;
using FredsCars.Models;
using FredsCars.Models.Repositories;
using MockQueryable;
using Moq;

namespace FredsCars.Tests.Controllers
{
    public class HomeControllerTests
    {
        [Fact]
        public async Task Can_Access_VehicleList_FromVehicleRepo()
        {
            // Arrange
            // 1 - create a List<T> with test items
            var vehicles = new List<Vehicle>
            {
                new Vehicle
                {
                    Id = 1,
                    Make = "Make1",
                    Model = "Model1",
                    VehicleType = new VehicleType
                    {
                        Id = 1,
                        Name = "Car"
                    }
                },
                new Vehicle
                {
                    Id = 2,
                    Make = "Make2",
                    Model = "Model2",
                    VehicleType = new VehicleType
                    {
                        Id = 1,
                        Name = "Car"
                    }
                },
                new Vehicle
                {
                    Id = 3,
                    Make = "Make3",
                    Model = "Model3",
                    VehicleType = new VehicleType
                    {
                        Id = 2,
                        Name = "Truck"
                    }
                },
                new Vehicle
                {
                    Id = 4,
                    Make = "Make4",
                    Model = "Model4",
                    VehicleType = new VehicleType
                    {
                        Id = 3,
                        Name = "Jeep"
                    }
                }
            };

            // 2 - build mock using MockQueryable.Moq extension 
            var mockVehiclesIQueryable = vehicles.BuildMock();

            // 3 - build mock IVehicleRepository
            Mock<IVehicleRepository> mockVehicleRepo =
                new Mock<IVehicleRepository>();
            mockVehicleRepo.Setup(mvr => mvr.Vehicles).Returns(mockVehiclesIQueryable);

            HomeController controller = new HomeController(mockVehicleRepo.Object);

            // Act
            IEnumerable<Vehicle>? result =
                (await controller.Index()).ViewData.Model
                    as IEnumerable<Vehicle>;

            // Assert
            Vehicle[] vehicleArray = result?.ToArray()
                ?? Array.Empty<Vehicle>();
            Assert.True(vehicleArray.Length == 4);
            int carCount = vehicleArray.Where(v => v.VehicleType.Name == "Car").Count();
            Assert.Equal(2, carCount);
            Assert.True(vehicleArray[2].Make == "Make3" &&
                vehicleArray[2].Model == "Model3");
            Assert.True(vehicleArray[3].Make == "Make4" &&
                vehicleArray[3].Model == "Model4");
        }
    }
}

If you run the new test the same way we ran its counterpart earlier, the result shows a green passing result.

Inspect the test code

In the code above for the new successful unit test in the new test file, we imported the MockQueryable namespace at the top of the file. But notice we also need to keep the reference to the Moq namespace.

using MockQueryable;
using Moq;

The test method itself is marked as async so that it can call the controller’s asynchronous Index method using the await keyword. It also has the Fact attribute to indicate that it is a unit test that should be run by the test runner.

[Fact]
public async Task Can_Access_VehicleList_FromVehicleRepo()
{
    ... existing code ...    
IEnumerable<Vehicle>? result =
    (await controller.Index()).ViewData.Model
        as IEnumerable<Vehicle>;
    ... existing code ...  
}

AAA (Arrange-Act-Assert) pattern in unit testing

Inside the body of the test method we use a common approach to software testing called the AAA (Arrange-Act-Assert) pattern.

There are three sections to the body of a test method with this pattern.

Arrange: Set up the necessary components, preconditions, and inputs.
Act: Perform the action or invoke the method being tested.
Assert: Verify the expected outcome via “assertions“.

public async Task Can_Access_VehicleList_FromVehicleRepo()
{
    // Arrange
    //    Setup test data, mocked repo, and instantiate the 
    //    Home controller with the mock repo

   // Act
   //  Use the HomeController component from the Arrange section 
   //   to call its Index method and capture its results 

   // Assert 
   //    Make assertions about the results from the Act section that must be true in
   //    order for the test to pass

Arrange Section

In the arrange section we create some test data, mock an IQueryable of Vehicle using the test data, mock an IVehicleRepository using the mock IQueryable, and finally instantiate the Home controller by injecting the mock IVehicleRepository into its constructor. This is our build up.

Create the test data

To create the test data we simply create a List of Vehicles much like we did in the failing version. The key difference here is that we don’t use the AsQueryable() method to convert the list to an IQueryable because we know this was the crux of our error. ASP.Net Core cannot call the results of a List or Array converted to IQueryable by the AsQueryable method though a mocked repo using the ToListAsync method in the Home controller’s Index method.

// Arrange
// 1 - create a List<T> with test items
var vehicles = new List<Vehicle>
{
    new Vehicle
    {
        Id = 1,
        Make = "Make1",
        Model = "Model1",
        VehicleType = new VehicleType
        {
            Id = 1,
            Name = "Car"
        }
    },
    new Vehicle
    {
        Id = 2,
        Make = "Make2",
        Model = "Model2",
        VehicleType = new VehicleType
        {
            Id = 1,
            Name = "Car"
        }
    },
    new Vehicle
    {
        Id = 3,
        Make = "Make3",
        Model = "Model3",
        VehicleType = new VehicleType
        {
            Id = 2,
            Name = "Truck"
        }
    },
    new Vehicle
    {
        Id = 4,
        Make = "Make4",
        Model = "Model4",
        VehicleType = new VehicleType
        {
            Id = 3,
            Name = "Jeep"
        }
    }
};
Mock the IQueryable<Vehicle> using MockQueryable package

The second thing we do in the arrange section is mock the IQueryable<Vehicle> by converting the List test data using the MockQueryable extension of the Moq package. This seems to be the step that fixes the error. After his point, the two versions of our test are basically the same.

// 2 - build mock using MockQueryable.Moq extension 
var mockVehiclesIQueryable = vehicles.BuildMock();
Build the mock IVehicleRepositoy

The third thing we do in the arrange section is build the mock IVehicleRepository by first instantiating an instance of Mock<IVehicleRepository> and then using the mock Setup and Returns methods to specify that the mocked Vehicle Repo’s Vehicles property returns the mocked IQueryable<Vehicle>. This differs from the original test where the IQueryable being returned was an Array<Vehicle> converted to an IQueryable with the AsQueryable method.

// 3 - build mock IVehicleRepository
Mock<IVehicleRepository> mockVehicleRepo =
    new Mock<IVehicleRepository>();
mockVehicleRepo.Setup(mvr => mvr.Vehicles).Returns(mockVehiclesIQueryable);
Instantiate the HomeController

Finally in the arrange section we instantiate an instance of the HomeController class and inject into its constructor the mocked Vehicle repo containing the mock IQueryable<Vehicle>

HomeController controller = new HomeController(mockVehicleRepo.Object);

Again, note we actually inject the Object property of the mock Vehicle repo.

Act Section

Now that we have “Arranged” and built up all of the objects we need for the unit test, we can “Act” on them.

The single statement in the Act section is the same as it was in the failing test except for the fact that now it works.

// Act
IEnumerable<Vehicle>? result =
    (await controller.Index()).ViewData.Model
        as IEnumerable<Vehicle>;

Here, we instantiate a variable called result of type nullable IEnumerable of Vehicle to capture the results, make the asynchronous call to the Home controller’s Index method using the await keyword, grab the DataDictionary (named ViewData) of the ViewResult being returned, get its Model and convert the model (IList<Vehicle>) to an IEnumerable of Vehicle. The IEnumerable<Vehicle> result is assigned to the result variable.

Assert Section

In the Assert section we start off by converting the results from the Act section to an Array to make it easier to work with and assign it to a variable of type Vehicle array named vehicleArray. If the result happens to be null, we use the null coalesce operator to assign an empty Array<Vehicle> to the result variable.

Vehicle[] vehicleArray = result?.ToArray()
    ?? Array.Empty<Vehicle>();

Finally, in the last four statements we can use the static methods of xUnit’s Assert object to verify our expected outcomes about the Vehicle array based on the test data we fed in.

The first Assert statement uses the Assert.True static method to verify the length of the Vehicle array is 4.

Assert.True(vehicleArray.Length == 4);

In the next two statements we use a LINQ query on vehicleArray to determine how many Vehicles in the vehicleArray variable are of type “Car” and assign the result to a variable named carCount of type int.
Then we use the static Assert.Equal method to verify the actual value in the carCount variable matches our expected amount of 2.

int carCount = vehicleArray.Where(v => v.VehicleType.Name == "Car").Count();
Assert.Equal(2, carCount);

The last two statements verify what we believe the Make and Model of the third and fourth elements in the array should be based on the test data we fed in.

Remember arrays are 0 index based to vehicleArray[2] is the third vehicle and vehicleArray[3] accesses the fourth vehicle.

Assert.True(vehicleArray[2].Make == "Make3" &&
    vehicleArray[2].Model == "Model3");
Assert.True(vehicleArray[3].Make == "Make4" &&
    vehicleArray[3].Model == "Model4");

At this point feel free to completely comment out the HomeControllerTests_Fails.cs file so its test will not show up in the Test Explorer anymore.


Assert methods

In the last section we saw how to use some static Assert methods to verify the outcome of our tests.

The Assert class provides a variety of assertion methods to validate expected outcomes in unit tests. The following are a few of the most commonly used methods.

Common xUnit Assert Methods

Equality Assertions
  • Assert.Equal(expected, actual): Verifies that two values are equal.
  • Assert.NotEqual(expected, actual): Verifies that two values are not equal.
Assert.Equal(10, 5 + 5);  // Passes
Assert.NotEqual(10, 4 + 5);  // Passes
Boolean Assertions
  • Assert.True(condition): Passes if the condition is true.
  • Assert.False(condition): Passes if the condition is false.
Assert.True(5 > 3);  // Passes
Assert.False(2 > 5); // Passes
Null Assertions
  • Assert.Null(object): Passes if the object is null.
  • Assert.NotNull(object): Passes if the object is not null.
object obj = null;
Assert.Null(obj); // Passes

obj = new object();
Assert.NotNull(obj); // Passes

There are quite a few Assert methods actually. Remember you can always use Intellisense to look for one that fits your need.

What’s Next

As usual we accomplished quite a bit in this module. We setup an xUnit project, installed the Moq package, mocked up our dependencies, and wrote our first test and watched it fail. We talked about the difficulties of mocking and testing asynchronous code.

Then we installed the MockQueryable.Moq package to help us with this issue, refactored our test and got a succeeding result.

Now that the HomeController is unit tested we should really also unit test the repository itself since it is a service. And that is what we are going to do in the next module.

< Prev
Next >

Leave a ReplyCancel reply

Chapter 1: Static HTML – Designing the landing page.

  • Static HTML – Designing the landing page.
  • Let’s get started!
  • Mock your site with HTML
  • Make CSS easy with Bootstrap
  • Mock your content
  • Introducing JavaScript
  • JavaScript Code Improvements
  • Results Data
  • Images and the HTML Image Element.
  • Revisiting Reusability for CSS and JavaScript
  • Reuse for HTML: PART 1
  • Reuse for HTML: PART 2
  • Details Page – Using a Bootstrap Component
  • Creating Links
  • Chapter One Conclusion

Chapter 2: ASP.Net Core – Let’s talk Dynamic

  • Introduction to ASP.Net Core
  • What is .Net?
  • What is ASP.Net
  • Introduction to Entity Framework Core

Chapter 3: ASP.Net MVC Core – Models, Views, and Controllers [ASP.Net Core v9]

  • Introduction to ASP.Net Core MVC
  • Create the project: ASP.Net Core MVC
  • Explore the ASP.Net Core Empty Web Project Template
  • Configure the Application for MVC
  • Create a Controller: Home Controller
  • Create a View: Index View for the Home Controller
  • Install Bootstrap using Libman
  • Create the Layout template
  • Create the Model
  • Install EF Core & Create the Database
  • Seed the Database: Loading test data
  • DI (Dependency Injection): Display a List of Vehicles
  • Repository Pattern: The Vehicles Repo
  • Unit Test 1: Home Controller Can Use Vehicle Repository
  • Unit Test 2: Vehicle Repository Can Return List
  • Add the ImagePath Migration and Thumbnail images to results
  • Pagination: Create a Custom Tag Helper
  • Sorting
  • Category Filter
  • Partial View: Break out the vehicle results
  • View Component: Create dynamic category buttons
  • Create the Details page
  • Create the Create Page

Chapter 7: Using Server Side & Client Side technologies together. [ASP.Net Core v7 & Angular v15]

  • Intro to Full Stack Development
  • Fred’s Cars – Full Stack Development
  • Prepare the environment
  • Create the Visual Studio Solution
  • Add the ASP.Net Core Web API project
  • Add the Angular Project
  • Wire it up!
  • WeatherForecast: Understanding the basics
  • Vehicles API Controller: Mock Data
  • Vehicles Angular Component: Consuming Data
  • Routing and Navigation
  • Using a Component Library: Angular Material
  • Our first Angular Material Component: MatToolbar
  • Configuring for Saas: CSS with superpowers
  • Create the Header & Footer components
  • Displaying Results with MatTable
  • Loading: Using a Progress Spinner
  • MatTable: Client-Side Paging and Sorting
  • MatSidenav: Create a Search Sidebar
  • MatCheckbox: Category Search UI
  • Adding an image to the welcome page
  • Create the database with Entity Framework Core migrations
  • MatPaginator & PageEvent: Custom Server-Side Paging
  • Unit Testing: Custom Server-Side Paging
  • Repository Pattern: VehicleRepository
  • Unit Test: Paging in the Vehicles controller
  • Server-Side Sorting
  • Unit Tests: Sorting
  • Filter (Quick Search)
  • Unit Tests: Filter feature
  • Advanced Search: Categories
  • Unit Tests: Search by category
  • Progress Spinner: Final Fix

TOC

  • What were WebForms?
  • Enter MVC
    • Understanding MVC
    • Advantages of MVC
  • ASP.Net Core MVC – A total rewrite
  • ASP.Net Core 2 MVC – Here come Razor Pages
    • Understanding Razor Pages
  • ASP.Net Core 3 – Dropping the MVC reference
    • Understanding Blazor
  • Dropping the MVC reference
  • Hello .Net 5!
  • What’s Next? – Here comes .Net 6.

Recent Posts

  • Angular Commands Cheat Sheet
  • Installing Git for Windows
  • Installing Postman
  • Installing SQL Server 2022 Express
  • Installing Visual Studio 2022

Recent Comments

No comments to show.

Archives

  • November 2023
  • October 2023
  • June 2023
  • October 2021

Categories

  • Angular
  • ASP.Net
  • Environment Setup
  • See All
  • SQL Server
  • Visual Studio
  • Web API & Rest Services

WordPress Theme Editor

Copyright © 2025 Web Development School.

Powered by PressBook Blog WordPress theme