0

I can't run tests for a controller doing Entity Framework Core operations in xUnit. I am using in-memory database and the error I am getting is:

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

The test class is:

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);
            }
        }
    }
}

The controller that is doing EF core operations is:

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();
        }
    }
}

The strange error while running the test shows up in Test Explorer - A test class may only define a single public constructor.

I could not find anything about it on stackoverflow. Please help in fixing it?

2
  • Have you tried making the constructor of TestRegistration public? Commented Jan 16, 2021 at 11:16
  • @AmanB yes i have tried it but no use at all. It then gives another errro which is The following constructor parameters did not have matching fixture data: DbContextOptions1 contextOptions` Commented Jan 16, 2021 at 11:17

1 Answer 1

1

Your constructor needs to be parameterless for this to work, unless you're using some DI framework within your testing project, which is something that you generally shouldn't be doing. Instead, try creating the DBContextOptions within the constructor and assigning it to your class variable. You can then use it when you seed the database, and when you test against it.

Try this instead. You will need to add the Microsoft.EntityFrameworkCore.InMemory package into your test project if you don't have this in there already.

public class TestRegistration
{
    #region Seeding
    public TestRegistration()
    {
        ContextOptions = new DbContextOptionsBuilder<AppDbContext>()
              .UseInMemoryDatabase(databaseName: "Test")
              .Options;
        Seed();
    }
Sign up to request clarification or add additional context in comments.

2 Comments

can you provide me full codes for it. thank you.
I've updated my answer. Let me know if this works for you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.