Модульный тест для начинающих в ASP.NET Контроллер Core 3 MVC

#c# #asp.net-mvc #visual-studio #unit-testing

#c# #asp.net-mvc #visual-studio #модульное тестирование

Вопрос:

Это первый раз, когда я пишу модульный тест для проекта .NET Core. Я попытался посмотреть учебник и посмотрел код в Интернете, но не могу найти решение для своего проекта.

Я CompanyController для модельной компании использую базу CodingChallegeDBContext данных и сервис IPaginatedListService , и я пытаюсь написать модульный тест для метода Index or Create .

Это тот самый Company класс

 using System.Collections.Generic; using System.ComponentModel.DataAnnotations;  namespace CodingChallenge.Models {  //Classe Company  public class Company  {  [Key]  public int CompanyCode { get; set; }   [Required]  public string CompanyName { get; set; }   [Required]  public string CompanyLogic { get; set; }   public Company()  {  }  } }  

Это CompanyController :

 using System; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using CodingChallenge.Data; using CodingChallenge.Models; using CodingChallenge.Services;  namespace CodingChallenge.Controllers {  public class CompanyController : Controller  {  private readonly CodingChallengeDBContext _context;   private readonly IPaginatedListServicelt;Companygt; _companyService;   public CompanyController(CodingChallengeDBContext context, IPaginatedListServicelt;Companygt; companyService)  {  _context = context;  _companyService = companyService;  }   public CompanyController()  {  }   public async Tasklt;IActionResultgt; Index(string sortOrder, string currentFilter, string searchString, int? pageNumber)  {  ViewData["CurrentSort"] = sortOrder;  ViewData["NameSortParm"] = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";   if (searchString != null)  {  pageNumber = 1;  }  else  {  searchString = currentFilter;  }   ViewData["CurrentFilter"] = searchString;   var company = from c in _context.Company  select c;   if (!String.IsNullOrEmpty(searchString))  {  company = company.Where(c =gt; c.CompanyName.Contains(searchString));  }   switch (sortOrder)  {  case "name_desc":  company = company.OrderByDescending(c =gt; c.CompanyName);  break;  default:  company = company.OrderBy(c =gt; c.CompanyName);  break;  }   int pageSize = 3;   return View(await PaginatedListServicelt;Companygt;.CreateAsync(company.AsNoTracking(), pageNumber ?? 1, pageSize));  }  public IActionResult Create()  {  return View();  }   //POST: Creazione  [HttpPost]  [ValidateAntiForgeryToken]  public async Tasklt;IActionResultgt; Create([Bind("CompanyCode,CompanyName,CompanyLogic")] Company company)  {  if (ModelState.IsValid)  {  //Controllo se esiste già un'azienda con lo stesso CompanyName e CompanyLogic  var company_compare = await _context.Company  .FirstOrDefaultAsync(c =gt; c.CompanyName == company.CompanyName);  if (company_compare != null)  {  TempData["Error"] = "The company "   company.CompanyName   " alredy exist";  return RedirectToAction("Create");  }   //Aggiunta della nuova azienda nel DB   _context.Add(company);  await _context.SaveChangesAsync();   //Endpoint dettagli dell'azienda creata  return RedirectToAction("Details", new { id = company.CompanyCode });  }   return View(company);  }  // some other methods  } }  

This is my PaginatedlistService :

 using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore;  namespace CodingChallenge.Services {  public class PaginatedListServicelt;Tgt; : Listlt;Tgt;, IPaginatedListServicelt;Tgt;  {  public PaginatedListService()  {   }   public int PageIndex { get; private set; }  public int TotalPages { get; private set; }   public PaginatedListService(Listlt;Tgt; items, int count, int pageIndex, int pageSize)  {  PageIndex = pageIndex;  TotalPages = (int)Math.Ceiling(count / (double)pageSize);   this.AddRange(items);  }   public bool HasPreviousPage  {  get  {  return (PageIndex gt; 1);  }  }   public bool HasNextPage  {  get  {  return (PageIndex lt; TotalPages);  }  }   public static async Tasklt;PaginatedListServicelt;Tgt;gt; CreateAsync(IQueryablelt;Tgt; source, int pageIndex, int pageSize)  {  var count = await source.CountAsync();  var items = await source.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync();  return new PaginatedListServicelt;Tgt;(items, count, pageIndex, pageSize);  }  } }  

это модульный тест, который я пробовал для метода создания, но он не работает, потому что я не могу передать контекст и службы контроллеру, который я пытался использовать, но я не понимаю, что нужно добавить в «результат», чтобы вернуть представление и что делать после

 [Fact]  public void CompanyCreate()  {  Company company = new Company();  company.CompanyName = "1";  company.CompanyLogic = " 1";  company.CompanyCode = 6;   CompanyController companycontroller = new CompanyController();   var result = companycontroller.Create(company);   Assert.IsTypelt;ViewResultgt;(result);  } --- mock  Company company = new Company();  company.CompanyName = "1";  company.CompanyLogic = " 1";  company.CompanyCode = 6;  mock.Mocklt;CompanyControllergt;()  .Setup(x =gt; x.Create(company))  .Returns();  var controller = mock.Createlt;Companygt;();  

Я думаю, что мне нужно использовать макет, но я пытался и потерпел неудачу, может ли кто-нибудь написать модульный тест для индекса метода или исправить модульный тест создания контроллера компании, чтобы я мог понять и написать другие модульные тесты для других методов или посоветовать мне хороший и простой учебник для выполнения?

Комментарии:

1. Это достойный вопрос, но было бы полезно, если бы вы удалили методы, которые вы не пытаетесь протестировать, например Create , методы. Кроме того, вызов статического метода PaginatedListServicelt;Tgt;.CreateAsync() сделает невозможным имитацию этой службы, что, в свою очередь, затруднит написание теста. Одним из подходов был бы IPaginatedListServiceFactory интерфейс вместо статического метода. Над этим было бы легче издеваться. Это не идеально, но это вариант.

2. Я вставляю метод Create, потому что, я думаю, проще написать модульный тест, поэтому я попробовал использовать этот метод для своего кода модульного теста, но не получилось. Я знаю, что сложнее указать метод для службы в конце, поэтому я попросил этот метод