嘿,我已经使用 .net core 创建了一个预约应用程序,问题是我删除了默认的 api 控制器中间件,以便在发生错误时生成自定义错误模式。为了检测错误并覆盖 .net 产生的默认错误,我抛出一个异常(自定义 HttpResponseException) 并在执行后修改IActionfilter处的异常。 现在我无法为抛出错误的代码部分编写单元测试。 测试停止执行并出现以下错误,请参阅下图。 有人可以帮忙吗??
我试过了
在单元测试中尝试catch(我已经评论了你可以看到的那部分)
我绑定了 Assert.Throws 技术 但我的代码从未达到这一点
我还尝试使用 dotnet run 运行我的应用程序,其中调试器处于关闭状态以避免 检测投掷并停止它,然后我尝试运行我的测试,但也失败了
如果您想了解该项目,请使用 git hub 链接到存储库: github链接
这是我编写测试的业务层代码,它是为 createAppointment 编写的:
using AppointmentApi.DataAccess;
using AppointmentApi.Models;
using AppointmentApi.validators;
namespace AppointmentApi.Buisness
{
public class AppointmentBL : IAppointmentBL
{
private readonly IAppointmentDL _appointmentDL;
public AppointmentBL(IAppointmentDL appointmentDL)
{
_appointmentDL = appointmentDL;
}
public List<Appointment> GetAppointments(AppointmentDateRequest appointmentDateRequest)
{
appointmentDateRequest.Validate<AppointmentDateRequest, AppointmentDateRequestValidator>();
return _appointmentDL.GetAppointments(date: appointmentDateRequest.Date);
}
public Guid CreateAppointment(AppointmentRequest appointmentrequest)
{
appointmentrequest.Validate<AppointmentRequest, AppointmentRequestValidator>();
DateOnly dateOnly = new DateOnly(appointmentrequest.StartTime.Year, appointmentrequest.StartTime.Month, appointmentrequest.StartTime.Day);
var appointments = _appointmentDL.GetAppointments(null, dateOnly);
var conflictingAppointment = appointments?.FirstOrDefault(item =>
(item.StartTime < appointmentrequest.StartTime && item.EndTime > appointmentrequest.StartTime) ||
(appointmentrequest.EndTime > item.StartTime && appointmentrequest.EndTime < item.StartTime));
if (conflictingAppointment != null)
{
var errorString = (conflictingAppointment.StartTime < appointmentrequest.StartTime ?
appointmentrequest.StartTime : appointmentrequest.EndTime) +
"is conflicting with an existing appointment having startTime:" +
$"{conflictingAppointment.StartTime} and endTime: {conflictingAppointment.EndTime}";
throw new HttpResponseException(StatusCodes.Status409Conflict, new CustomError { Message = errorString });
}
return _appointmentDL.CreateAppointment(appointmentrequest);
}
public void DeleteAppointment(Guid id)
{
var result = _appointmentDL.GetAppointments(id, null);
if (result.Count == 0)
{
throw new HttpResponseException(StatusCodes.Status404NotFound, new CustomError(){Message="Appointment not found"});
}
_appointmentDL.DeleteAppointment(id);
}
}
}
失败的单元测试代码:
[Fact]
public void TestCreateAppointment_Throws_conflictError()
{
var mockAppointmentDL = new Mock<IAppointmentDL>();
var appointmentBL = new AppointmentBL(mockAppointmentDL.Object);
var appointmentRequest2 = new AppointmentRequest
{
Title = "New Test Appointment",
StartTime = DateTime.Parse("2023/10/3 10:20"),
EndTime = DateTime.Parse("2023/10/3 11:00")
};
var appointmentRequest1 = new AppointmentRequest
{
Title = "New Test Appointment",
StartTime = DateTime.Parse("2023/10/3 09:00"),
EndTime = DateTime.Parse("2023/10/3 10:20")
};
var appointments = new List<Appointment>
{
new Appointment { Title = "Go To Gym", StartTime = DateTime.Parse("2023/10/3
10:00"), EndTime = DateTime.Parse("2023/10/3 11:00") }
};
DateOnly dateOnly = new DateOnly(appointmentRequest2.StartTime.Year,
appointmentRequest2.StartTime.Month, appointmentRequest2.StartTime.Day);
mockAppointmentDL.Setup(x => x.GetAppointments(null, dateOnly)).Returns(appointments);
var expectedGuid = Guid.NewGuid();
mockAppointmentDL.Setup(x =>
x.CreateAppointment(appointmentRequest2)).Returns(expectedGuid);
var errorDto = new CustomError() { Message = "Appoinment conflict" };
// Act
var result = appointmentBL.CreateAppointment(appointmentRequest2);
var result2 = appointmentBL.CreateAppointment(appointmentRequest1);
// Assert
var exception = Assert.Throws<HttpResponseException>(() =>
appointmentBL.CreateAppointment(appointmentRequest2));
Assert.Equal(409, exception.Status);
//failed
// try
// {
// appointmentBL.CreateAppointment(appointmentRequest2);
// }
// catch (HttpResponseException exception)
// {
// Assert.Equal(StatusCodes.Status409Conflict, exception.Status);
// }
//failed
// var exception = Record.Exception(() =>
// appointmentBL.CreateAppointment(appointmentRequest2));
// Assert.NotNull(exception);
// Assert.IsType<HttpResponseException>(exception);
// var httpResponseException = (HttpResponseException)exception;
// Assert.Equal(409, httpResponseException.Status);
}
mockAppointmentDL 设置为返回与单元测试的 //Act 部分中的两个 CreateAppointment 调用冲突的约会。
如果您希望测试通过,则应删除 //Act 部分(所有 AppointmentBL.CreateAppointment 调用应位于 Assert.Throws lambda 中)