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 2: Vehicle Repository Can Return List

In the last module we unit tested the HomeController component.

In this module we will unit test the EFVehicleRepository service.

Table Of Contents
  1. Create the Repositories test folder
  2. Create the Repo unit test file
  3. Write the Unit Test
  4. Fix the System.NotSupportedException – Non-overridable members error.
    • Lambda property expressions in C#
    • Virtual Properties in C#
  5. Fix the System.ArgumentException – Cannot instantiate proxy (FredsCarsDbContext
  6. The Act Section
  7. The Assert Section
  8. What's Next

Create the Repositories test folder

Create a new folder on the root of the FredsCars.Tests project and name it Models and create a new subfolder under it named Repositories.

Create the Repo unit test file

In the new Repositories folder create a new class file called EFVehicleRepositoryTests.cs.

Write the Unit Test

Modify EFVehicleRepositoryTests.cs with the code below.

FredsCars\FredsCars.Tests\Models\Repositories\EFVehicleRepositoryTests.cs

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

namespace FredsCars.Tests.Models.Repositories
{
    public class EFVehicleRepositoryTests
    {
        [Fact]
        public void Can_Return_VehicleList()
        {
            // 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 DbSet
            var mockVehiclesDbSet = vehicles.AsQueryable().BuildMockDbSet();

            // 3 - mock FredsCarsDbSet
            Mock<FredsCarsDbContext> mockFCDbContext =
                new Mock<FredsCarsDbContext>();
            mockFCDbContext.SetupGet(m => m.Vehicles)
                .Returns(mockVehiclesDbSet.Object);

            // 4 - instantiate EFVehicleRepository
            EFVehicleRepository repo 
                = new EFVehicleRepository(mockFCDbContext.Object);

            // Act 
            IQueryable<Vehicle> vehicleList = repo.Vehicles;

            // Assert
            Vehicle[] vehicleArray = vehicleList.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");

        }
    }
}

Fix the System.NotSupportedException – Non-overridable members error.

If you run the Can_Return_VehicleList test at this point, you get an error message that says:

Message: 
System.NotSupportedException : Unsupported expression: m => m.Vehicles
Non-overridable members (here: FredsCarsDbContext.get_Vehicles) may not be used in setup / verification expressions.


Let’s inspect the code and see if we can uncover the reason for and meaning of this error.

In the arrange section we first create a List of Vehicles representing our test data much like the first unit test we wrote.

Unlike the last unit test where we used the MockQueryable package to convert the test data to an IQueryable for the repo to return, here we convert the test data to a DbSet for a mocked FredsCarsDbContext to return via its Vehicles property.

var mockVehiclesDbSet = vehicles.AsQueryable().BuildMockDbSet();

Again, the MockQueryable package comes in handy with it’s BuildMockDbSet method shown in the above line. Notice we first have to convert the vehicles variable to an IQueryable with the AsQueryable method.

The next step is where we get the error. Now that we have a mocked DbSet of Vehicle test data, we should be able to return it from a mocked FredsCarsDbContext via its Vehicles property. Right?

Mock<FredsCarsDbContext> mockFCDbContext =
    new Mock<FredsCarsDbContext>();
mockFCDbContext.SetupGet(m => m.Vehicles)
    .Returns(mockVehiclesDbSet.Object);

In the above code we use the SetupGet method rather than Setup because the Vehicles DbSet property of FredsCarsDbContext is readonly meaning it only implements the Get accessor of the property and not the Set accessor. But it still does not fix our problem.

Lambda property expressions in C#

The crux of the error is that Vehicles is a read only property of FredsCarsDbContext.

public DbSet<Vehicle> Vehicles => Set<Vehicle>();

In the above line we use the Lambda “goes into” (=>) operator to create a property expression that returns a DbSet<Vehicle>. The Set<Vehicle> method creates the DbSet that can be used to create and save instances of Vehicle.

In C#, lambda property expressions allow you to define read-only properties, providing a concise and expressive way to implement properties. These are useful for simple computed properties that return a value without needing a backing field.

And this is what the error message is trying to tell us. Here is the error message once again.

Message: 
System.NotSupportedException : Unsupported expression: m => m.Vehicles
Non-overridable members (here: FredsCarsDbContext.get_Vehicles) may not be used in setup / verification expressions.

The FredsCarsDbContext.Vehicles property is read only and therefor we cannot override its Get accessor.

Virtual Properties in C#

In order to fix this error we need to make the Vehicles DbSet property in FredsCarsDbContext virtual so we can override it. Modify the FredsCarsDbContext with the code below.

FredsCars\FredsCars\Data\FredsCarsDbContext.cs

... existing code ...
public FredsCarsDbContext(DbContextOptions<FredsCarsDbContext> options)
    : base(options) 
{}

public virtual DbSet<Vehicle> Vehicles => Set<Vehicle>();
public DbSet<VehicleType> VehicleTypes => Set<VehicleType>();
... existing code ...

In the code above we simply added the virtual reserved word to the Vehicles property.


In C#, a virtual property is a property that can be overridden in derived classes. This is useful in inheritance when you want to allow subclasses to provide their own implementation of a property while still maintaining a common interface in the base class.

Here we allowed the Moq package to override the Vehicles property in order to create our mocked FredsCarsDbContext.

Fix the System.ArgumentException – Cannot instantiate proxy (FredsCarsDbContext

If we run the test at this point we now get another error:

Message: 
System.ArgumentException : Can not instantiate proxy of class: FredsCars.Data.FredsCarsDbContext.
Could not find a parameterless constructor. (Parameter ‘constructorArguments’)
—- System.MissingMethodException : Constructor on type ‘Castle.Proxies.FredsCarsDbContextProxy’ not found.

This happens at line 74 in the test.

EFVehicleRepository repo 
    = new EFVehicleRepository(mockFCDbContext.Object);

It’s saying that even though we have fixed the read only property issue, Moq still cannot instantiate an instance of FredsCarsDbContext to inject into an EFVehcileRepository because the only constructor available expects a parameter of type DbContextOptions<FredsCarsDbContext.

But for our test we are not not using a real database so we do not need the Db options information. We mocked the DbSet we need to return instead. To fix this error modify FredsCarsDbContext with the code shown below.

FredsCars\Data\FredsCarsDbContext.cs

using FredsCars.Models;
using Microsoft.EntityFrameworkCore;

namespace FredsCars.Data
{
    public class FredsCarsDbContext : DbContext
    {
        public FredsCarsDbContext()
        {
        }

        public FredsCarsDbContext(DbContextOptions<FredsCarsDbContext> options)
            : base(options) 
        {}

        public virtual DbSet<Vehicle> Vehicles => Set<Vehicle>();
        public DbSet<VehicleType> VehicleTypes => Set<VehicleType>();
... existing code ...

In the above code we simply added a parameterless constructor to FredsCarsDbContext for the unit test and Moq to use.


If we run the test at this point it should give a passing result.

The Act Section

With the arrange section all setup and doing its job to set up the needed mocks and instantiate an EFVehicleRepository instance, we can now call the repo’s Vehicles property and assign the results to an IQueryable<Vehicle>.

// Act 
IQueryable<Vehicle> vehicleList = repo.Vehicles;

The Assert Section

The assert section is the same as in the first unit test of the Home Controller’s Index method. We convert vehilceList results from an IQueryable<Vehicle> to an array and all the assertions are the same since we use the same test data.

What’s Next

In this module we unit tested the EFVehicleRepository class’s implementation of the IVehicleRepository. Now that our project is fully unit tested up to this point we can return back to working on the features of the applicaiton.

In the next section we are going to add a thumbnail image of each vehicle to its record in the results. We will need to put these images under the wwwroot folder and add a migration to add a property to the Vehicle entity class containing the pathway to its image.

< 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