Не удается запустить тесты для контроллера, выполняющего основные операции Entity Framework в xUnit

#asp.net-core #xunit

#asp.net-core #xunit

Вопрос:

Я не могу запускать тесты для контроллера, выполняющего основные операции Entity Framework в xUnit. Я использую базу данных в памяти, и я получаю ошибку:

 **A test class may only define a single public constructor.**
 

Тестовый класс:

 using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using MyAppT.Controllers;
using MyAppT.Models;
using Xunit;

namespace TestingProject
{

    public class TestRegistration
    {
        #region Seeding
        protected TestRegistration(DbContextOptions<AppDbContext> contextOptions)
        {
            ContextOptions = contextOptions;
            Seed();
        }

        protected DbContextOptions<AppDbContext> ContextOptions { get; }

        private void Seed()
        {
            using (var context = new AppDbContext(ContextOptions))
            {
                context.Database.EnsureDeleted();
                context.Database.EnsureCreated();

                var one = new Register()
                {
                    Name = "Test One",
                    Age = 40
                };

                var two = new Register()
                {
                    Name = "Test Two",
                    Age = 50
                };

                var three = new Register()
                {
                    Name = "Test Three",
                    Age = 60
                };
                context.AddRange(one, two, three);
                context.SaveChanges();
            }
        }
        #endregion

        [Fact]
        public void Test_Create_GET_ReturnsViewResultNullModel()
        {
            using (var context = new AppDbContext(ContextOptions))
            {
                // Arrange
                var controller = new RegistrationController(context);

                // Act
                var result = controller.Create();

                // Assert
                var viewResult = Assert.IsType<ViewResult>(result);
                Assert.Null(viewResult.ViewData.Model);
            }
        }
    }
}
 

Контроллер, выполняющий основные операции EF, является:

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

namespace MyAppT.Controllers
{
    public class RegistrationController : Controller
    {
        private AppDbContext context;
        public RegistrationController(AppDbContext appDbContext)
        {
            context = appDbContext;
        }

        public IActionResult Create()
        {
            return View();
        }

        [HttpPost]
        public async Task<IActionResult> Create(Register register)
        {
            if (ModelState.IsValid)
            {
                context.Add(register);
                await context.SaveChangesAsync();

                return RedirectToAction("Read");
            }
            else
                return View();
        }
    }
}
 

Странная ошибка при выполнении теста отображается в Test Explorer — тестовый класс может определять только один общедоступный конструктор.

Я ничего не смог найти об этом в stackoverflow. Пожалуйста, помогите это исправить?

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

1. Вы пробовали создать конструктор TestRegistration public?

2. @AmanB да, я пробовал, но вообще бесполезно. Затем он выдает другую ошибку, которая равна The following constructor parameters did not have matching fixture data: DbContextOptions 1 contextOptions `

Ответ №1:

Чтобы это работало, ваш конструктор должен быть без параметров, если только вы не используете какую-либо платформу DI в своем проекте тестирования, чего обычно делать не следует. Вместо этого попробуйте создать DbContextOptions в конструкторе и присвоить его переменной вашего класса. Затем вы можете использовать его при заполнении базы данных и при тестировании с ней.

Попробуйте это вместо этого. Вам нужно будет добавить Microsoft.EntityFrameworkCore.InMemory пакет в свой тестовый проект, если у вас его там еще нет.

 public class TestRegistration
{
    #region Seeding
    public TestRegistration()
    {
        ContextOptions = new DbContextOptionsBuilder<AppDbContext>()
              .UseInMemoryDatabase(databaseName: "Test")
              .Options;
        Seed();
    }
 

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

1. можете ли вы предоставить мне полные коды для этого. Спасибо.

2. Я обновил свой ответ. Дайте мне знать, если это сработает для вас.