提问人:vishwa Tj 提问时间:11/2/2023 最后编辑:marc_svishwa Tj 更新时间:11/2/2023 访问量:37
我无法在 .net 的 Xunit 测试中检测到抛出,我的测试在抛出时终止?
I'm not able to detect throw in Xunit testing in .net, my test is terminating at throw?
问:
嘿,我已经使用 .net core 制作了一个约会应用程序,问题是我删除了默认的 api 控制器中间件,以便在发生错误时生成自定义错误架构。检测错误并覆盖 .net 生成的默认错误,我抛出异常(自定义 HttpResponseException) 并在执行后修改 IActionfilter 中的异常。 现在,我无法为抛出错误的代码部分编写单元测试测试。 测试停止执行,并出现以下错误,请参阅下图。 谁能帮忙??
我试过了
在单元测试中尝试catch(我已经评论了你可以看到的那部分)
我绑定了 Assert.Throws 技术 但我的代码永远无法达到重点
我还尝试在调试器关闭的情况下使用 dotnet run 运行我的应用程序,以避免 检测到投掷并停止它,然后我尝试运行我的测试,但测试也失败了
如果你想了解这个项目,Git Hub 链接到 repo : 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);
}
答:
0赞
Tenatus
11/2/2023
#1
mockAppointmentDL 设置为返回与单元测试的 //Act 部分中的两个 CreateAppointment 调用冲突的约会。
如果你想让测试通过,应该删除 //Act 部分(所有的 appointmentBL.CreateAppointment 调用都应该在 Assert.Throws lambdas 中)
评论
0赞
vishwa Tj
11/9/2023
没错,我必须删除 Act 部分以检测未在正在测试的同一代码文件中处理的自定义抛出。
0赞
vishwa Tj
11/9/2023
Act & Assert Assert.Throws<HttpResponseException>(() => appointmentBL.CreateAppointment(appointmentRequest));mockAppointmentDL.Verify(x => x.GetAppointments(null, dateOnly), Times.Once);
评论
AppointmentBLTest.cs