Abhilash Narayan
Abhilash Narayan

Reputation: 157

What should I pass to controller in order to perform model unit testing in ASP.NET Core 2.0

How to perform model unit testing in .net core 2.0? I am not getting what to pass to Homecontroller class in unit testing class. This is my unit testing class where I need help

enter image description here

using BasicUnitTesting.Models;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using BasicUnitTesting.Controllers;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Linq;

namespace BasicUnitTestProj
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void GetEmployeeTest()
        {
            HomeController home = new HomeController(null); //What should i pass to HomeController

            var vr = home.GetEmployee() as ViewResult;

            List<Employee> expectedemps = new List<Employee>()
            {
                new Employee() {EmpID=101,EmpName="Abhilash",Salary=50000},
                new Employee() {EmpID=102,EmpName="Abhishek",Salary=60000},
                new Employee() {EmpID=103,EmpName="Nagraj",Salary=30000},
                new Employee() {EmpID=104,EmpName="Sunil",Salary=50000},
                new Employee() {EmpID=105,EmpName="Vinay",Salary=40000}
            };

            Assert.IsTrue(expectedemps.SequenceEqual(vr.Model as List<Employee>));
        }
    }
}

Below is my Homecontroller

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using BasicUnitTesting.Models;

namespace BasicUnitTesting.Controllers
{
    public class HomeController : Controller
    {
        private readonly CompanyDbContext _context

        public HomeController(CompanyDbContext context)
        {
            _context = context;
        }

        public IActionResult Index()
        {
            return View("Index");
        }

        public IActionResult GetEmployee()
        {
            //CompanyDbContext Db = new CompanyDbContext();
            //List<Employee> emps = Db.Employees.ToList();
            List<Employee> emps = _context.Employees.ToList();
            return View(emps);
        }         
    }
}

My model and Context class are as follows:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
using Microsoft.EntityFrameworkCore;

namespace BasicUnitTesting.Models
{
    public class Employee
    {
        [Key]
        public int EmpID { get; set; }
        public string EmpName { get; set; }
        public decimal Salary { get; set; }
    }

    public class CompanyDbContext:DbContext
    {
        public CompanyDbContext()
        {
        }

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

        public DbSet<Employee> Employees { get; set; }
    }
}

Upvotes: 1

Views: 251

Answers (1)

user007
user007

Reputation: 1192

You should pass abstraction/interface to your Controller, it should not know about details/implementation of your DbContext.

What you need is another Interface/Contract:

public interface ICompanyDbContext
{
   DbSet<Employee> Employees { get; set; }
}

and your class should implement this interface:

public class CompanyDbContext: ICompanyDbContext, DbContext

Your controller should have argument of ICompanyDbContext not CompanyDbContext:

public HomeController(ICompanyDbContext context)

This allows you to mock ICompanyDbContext in your unit test:

var dbContext = new Mock<ICompanyDbContext>();
// you should SetUp mock as well as do verification on it

HomeController home = new HomeController(dbContext.Object); 

Upvotes: 1

Related Questions