#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, потому что, я думаю, проще написать модульный тест, поэтому я попробовал использовать этот метод для своего кода модульного теста, но не получилось. Я знаю, что сложнее указать метод для службы в конце, поэтому я попросил этот метод