Исключение предполагает, что вы не зарегистрировали свой DBContext в своем Startup.cs (как упоминалось выше). Я также предлагаю вам изменить имя вашего частного свойства только для чтения на что-то другое, кроме DbContext (которое является именем класса и может запутать). Используйте что-то вроде этого:
private readonly ApptSystemContext _context;
Кроме того, ваш подход следует изменить.
Во-первых, вы установите строку подключения при регистрации DBContext. Просто позвольте инъекции зависимостей позаботиться об этом за вас. Ваш контроллер должен выглядеть так:
public apptController(ApptSystemContext dbContext)
{
_context = dbContext;
}
dbContext не будет нулевым, если вы зарегистрируете его в Startup.
Далее, модульное тестирование - сложная концепция, но как только вы напишете свой Модульный тест, вы начнете понимать немного лучше.
Вы сказали, что хотите использовать базу данных SQL In Memory для модульного тестирования, что является хорошим подходом (имейте в виду, что есть ограничения до SQL В Mem, как без ограничений FK). Затем я предполагаю, что вы хотите протестировать свой контроллер, поэтому, поскольку вы ДОЛЖНЫ передать DBContext, чтобы создать экземпляр своего контроллера, вы можете создать новый экземпляр DBContext, который настроен для использования базы данных в памяти.
Например,
public void ApptControllerTest()
{
//create new dbcontext
DbContextOptions<ApptSystemContext> options;
var builder = new DbContextOptionsBuilder<ApptSystemContext>();
builder.UseInMemoryDatabase();
options = builder.Options;
var context = new ApptSystemContext(options);
//instantiate your controller
var controller = new appController(context);
//call your method that you want to test
var retVal = controller.assignAppt(args go here);
}
Измените тело метода на это:
public string assignAppt([FromBody] dynamic apptData)
{
int id = apptData.SlotId;
string json = apptData.ApptJson;
DateTime timeStamp = DateTime.Now;
using (_context)
{
var slot = _context.AppointmentSlots.Single(s => s.SlotId == id);
// make sure there isn't already an appointment booked in appt slot
if (slot.Timestamp == null)
{
slot.ApptJson = json;
slot.Timestamp = timeStamp;
_context.SaveChanges();
return "Task Executed\n";
}
else
{
return "There is already an appointment booked for this slot.\n" +
"If this slot needs changing try updating it instead of assigning it.";
}
}
}
Еще одно предложение: не используйте объект Dynami c в качестве тела запроса, если вы не абсолютно вынуждены это сделать. Использование объекта Dynami c позволяет передавать что угодно, и вы теряете возможность определять, является ли запрос приемлемым или нет.