我无法在.net 中的 Xunit 测试中检测到 throw,我的测试在 throw 处终止?

问题描述 投票:0回答:1

嘿,我已经使用 .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);
        }

c# .net try-catch webapi throw
1个回答
0
投票

mockAppointmentDL 设置为返回与单元测试的 //Act 部分中的两个 CreateAppointment 调用冲突的约会。

如果您希望测试通过,则应删除 //Act 部分(所有 AppointmentBL.CreateAppointment 调用应位于 Assert.Throws lambda 中)

© www.soinside.com 2019 - 2024. All rights reserved.