使用 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
}
我目前正在学习 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
}