使用 NUnit 在单元测试期间实现接口列表

Implement a list of interfaces during Unit Test using NUnit

我目前正在学习 C#,我对一个简单的任务感到震惊。 我有这段代码要测试:

    public interface IAppointment
{
    public string PatientName { get; set; }
    public IEnumerable<DateTime> ProposedTimes { get; set; }
    public DateTime? SelectedAppointmentTime { set; }
}

public static class MedicalScheduler
{
    public static Dictionary<DateTime, string> Appointments { get; set; } = new Dictionary<DateTime, string>();
    public static List<DateTime> FreeSlots { get; set; } = new List<DateTime>();

    public static IEnumerable<Tuple<string, bool>> Schedule(IEnumerable<IAppointment> requests)
    {
        bool slotFound = false;
        foreach (var appointment in requests)
        {
            if (slotFound) continue;

            foreach (var times in appointment.ProposedTimes)
            {
                var freeSlot = FreeSlots.Where(s => s.Date == times.Date).FirstOrDefault();

                if (freeSlot != null)
                {
                    slotFound = true;
                    Appointments.Remove(freeSlot);
                    appointment.SelectedAppointmentTime = freeSlot;
                    yield return new Tuple<string, bool>(appointment.PatientName, true);
                }
            }

            yield return new Tuple<string, bool>(appointment.PatientName, false);
        }
    }
}

而且我需要用一组特定的参数来测试“时间表”。例如,我需要使用空的 Appointments 和 FreeList 来测试它,但要使用“requests”中的单个元素。 我想我已经了解了如何编译单元测试并设置 Dictionary 和 List 参数。但我不确定如何创建 IEnumerable 变量。 我的想法是创建一个 IAppointment(s) 列表,但如何在测试单元中实现该接口?我尝试过使用 Moq,但我不明白应该如何正确使用它。

如果请求看起来很混乱,我很抱歉,但我不知道如何更好地解释:)

在此先感谢您的帮助。

请看下面的例子:

[Test]
public void Schedule()
{
    // Arrange
    var appointmentMock = new Mock<IAppointment>();
    appointmentMock.Setup(appointment => appointment.PatientName).Returns("Dixie Dörner");
    appointmentMock.Setup(appointment => appointment.ProposedTimes).Returns(
        new List<DateTime>
        {
            new DateTime(1953,4,12), 
            new DateTime(1953,4,13)
        });
    var requests = new List<IAppointment>{appointmentMock.Object};

    // Act
    var results = MedicalScheduler.Schedule(requests);

    // Assert
    Assert.IsTrue(results.Any());
    // results.Should().HaveCount(1); // If you're using FluentAssertions
}

MedicalScheduler.Schedule 接受任何实现 IEnumerable<IAppointment> 的参数,例如。 G。 List<IAppointment>Collection<IAppointment>.

所以您只需创建一个 List<IAppointment> 并用 IAppointment.

的自定义实例填充它

您可以使用 Moq 创建实例,就像我在示例中所做的那样。但是对于我自己的项目,我更喜欢构建器模式:

internal static class AppointmentBuilder
{
    public static IAppointment CreateDefault() => new Appointment();

    public static IAppointment WithPatientName(this IAppointment appointment, string patientName)
    {
        appointment.PatientName = patientName;
        return appointment;
    }
    
    public static IAppointment WithProposedTimes(this IAppointment appointment, params DateTime[] proposedTimes)
    {
        appointment.ProposedTimes = proposedTimes;
        return appointment;
    }
    
    private class Appointment : IAppointment
    {
        public string PatientName { get; set; }
        public IEnumerable<DateTime> ProposedTimes { get; set; }
        public DateTime? SelectedAppointmentTime { get; set; }
    }
}

[Test]
public void Schedule()
{
    // Arrange
    var requests = new List<IAppointment>{AppointmentBuilder.CreateDefault()
        .WithPatientName("Dixie")
        .WithProposedTimes(new DateTime(1953,4,12))};

    // Act
    var results = MedicalScheduler.Schedule(requests);

    // Assert
    Assert.IsTrue(results.Any());
    // results.Should().HaveCount(1); // If you're using FluentAssertions
}