I have an XUnit project that references and tests an API endpoint method of another project. When I run the test however I get the following error:
A test class may only define a single public constructor.
Haven't been able to find much about what this issue might mean but I'll provide the code samples below. Any help is greatly appreciated.
APIControllerTest.cs
using System;
using System.Collections.Generic;
using AppointmentAPI.Controllers;
using AppointmentAPI.Appt_Models;
using Microsoft.EntityFrameworkCore;
using Xunit;
namespace AppointmentAPITests
{
public class APIControllerTests
{
#region Seeding
protected APIControllerTests(DbContextOptions<ApptSystemContext> contextOptions)
{
ContextOptions = contextOptions;
Seed();
}
protected DbContextOptions<ApptSystemContext> ContextOptions { get; }
private void Seed()
{
using (var context = new ApptSystemContext(ContextOptions))
{
// this ensures that a fresh in-memory db is used for each test
context.Database.EnsureDeleted();
context.Database.EnsureCreated();
var one = context.AppointmentSlots.Add(new AppointmentSlots
{
SlotId = 1,
Date = Convert.ToDateTime("2020-03-31 00:00:00.000"),
Time = TimeSpan.Parse("12:00:00.0000000"),
ApptJson = "{'fname':'Billy','lname':'Joel','age':70,'caseWorker':'Donna', 'appStatus':'finished'}",
Timestamp = Convert.ToDateTime("2020-02-24 12:00:00.000")
});
var two = context.AppointmentSlots.Add(new AppointmentSlots
{
SlotId = 2,
Date = Convert.ToDateTime("2020-02-14 00:00:00.000"),
Time = TimeSpan.Parse("10:30:00.0000000"),
ApptJson = "{'fname':'Nick','lname':'Nicholas','age':25,'caseWorker':'Brenda', 'appStatus':'finished'}",
Timestamp = Convert.ToDateTime("2020-02-10 11:38:00.000")
});
var three = context.AppointmentSlots.Add(new AppointmentSlots
{
SlotId = 3,
Date = Convert.ToDateTime("2020-01-02 00:00:00.000"),
Time = TimeSpan.Parse("03:45:00.0000000"),
ApptJson = "{'fname':'Macey','lname':'Johnson','age':43,'caseWorker':'Donna', 'appStatus':'unfinished'}",
Timestamp = Convert.ToDateTime("2020-01-01 09:34:00.000")
});
var four = context.AppointmentSlots.Add(new AppointmentSlots
{
SlotId = 4,
Date = Convert.ToDateTime("2020-05-17 00:00:00.000"),
Time = TimeSpan.Parse("01:15:00.0000000"),
ApptJson = "{'fname':'James','lname':'Wally','age':35,'caseWorker':'Brad', 'appStatus':'finished'}",
Timestamp = Convert.ToDateTime("2020-04-28 02:03:00.000")
});
var five = context.AppointmentSlots.Add(new AppointmentSlots
{
SlotId = 5,
Date = Convert.ToDateTime("2019-11-23 00:00:00.000"),
Time = TimeSpan.Parse("12:45:00.0000000"),
ApptJson = "{'fname':'Emily','lname':'Carlton','age':62,'caseWorker':'Brenda', 'appStatus':'unfinished'}",
Timestamp = Convert.ToDateTime("2019-11-19 11:07:00.000")
});
var six = context.AppointmentSlots.Add(new AppointmentSlots
{
SlotId = 6,
Date = Convert.ToDateTime("2020-07-24 00:00:00.000"),
Time = TimeSpan.Parse("10:00:00.0000000"),
ApptJson = "{'fname':'Michael','lname':'Smith','age':52,'caseWorker':'Donna', 'appStatus':'finished'}",
Timestamp = Convert.ToDateTime("2020-06-25 09:34:00.000")
});
var seven = context.AppointmentSlots.Add(new AppointmentSlots
{
SlotId = 7,
Date = Convert.ToDateTime("2020-05-19 00:00:00.000"),
Time = TimeSpan.Parse("08:45:00.0000000"),
ApptJson = null,
Timestamp = null
});
var eight = context.AppointmentSlots.Add(new AppointmentSlots
{
SlotId = 8,
Date = Convert.ToDateTime("2020-06-05 00:00:00.000"),
Time = TimeSpan.Parse("02:45:00.0000000"),
ApptJson = null,
Timestamp = null
});
var nine = context.AppointmentSlots.Add(new AppointmentSlots
{
SlotId = 9,
Date = DateTime.Now.AddMonths(2),
Time = TimeSpan.Parse("02:45:00.0000000"),
ApptJson = null,
Timestamp = null
});
context.AddRange(one, two, three, four, five, six, seven, eight, nine);
context.SaveChanges();
}
}
#endregion
#region AssignAppts
[Fact]
public void TestAssignAppts()
{
using (var context = new ApptSystemContext(ContextOptions))
{
var controller = new apptController(context);
// Arrange
var request = new AppointmentAPI.Appt_Models.AppointmentSlots
{
SlotId = 7,
ApptJson = "{'fname':'Emily','lname':'Carlton','age':62,'caseWorker':'Brenda', 'appStatus':'unfinished'}",
Timestamp = Convert.ToDateTime("2020-06-25 09:34:00.000")
};
string expectedResponse = "Task Executed\n";
// Act
var response = controller.assignAppt(request);
// Assert
Assert.Equal(response, expectedResponse);
}
}
#endregion
}
}
sqliteInMemoryAPIController.cs
using System;
using System.Collections.Generic;
using System.Data.Common;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using AppointmentAPI.Appt_Models;
namespace AppointmentAPITests
{
#region SqliteInMemory
class SqliteInMemoryAPIController : APIControllerTests, IDisposable
{
private readonly DbConnection _connection;
private SqliteInMemoryAPIController()
: base(
new DbContextOptionsBuilder<ApptSystemContext>()
.UseSqlite(CreateInMemoryDatabase())
.Options)
{
_connection = RelationalOptionsExtension.Extract(ContextOptions).Connection;
}
private static DbConnection CreateInMemoryDatabase()
{
var connection = new SqliteConnection("Filename:=memory:");
connection.Open();
return connection;
}
public void Dispose() => _connection.Dispose();
}
#endregion
}
a single **public** constructor
. Your constructor isprivate
– MinnySqliteInMemoryAPIController
to public but I still get the same error – RollieAPIControllerTests
. You need to instantiate required context options in the constructor. In XUnit test class constructor is entry point of all tests. – Lauritz