为了账号安全,请及时绑定邮箱和手机立即绑定

使用 NUnit 对 DateTime 控制器进行单元测试

使用 NUnit 对 DateTime 控制器进行单元测试

C#
慕仙森 2023-09-24 10:54:04
我正在创建一个 React / .NET Core 项目,其中一个页面显示当前日期和时间。我的控制器类如下:namespace TestingReactDotNet.Controllers {    [Route ("api/[controller]")]    public class DayTodayController : Controller {        [HttpGet, Route ("GetDate")]        public  string GetDate () {            var info = $"Today is {DateTime.Now.ToString("dddd, dd MMMM yyyy")} and the time is {DateTime.Now.ToString("hh:mm tt")}";            return info;        }    }}我正在尝试对其进行单元测试并模拟日期和时间,但正在努力做到这一点(我已经查看了其他 Stack Overflow 问题并用 Google 搜索,但我仍然遇到了麻烦)。本来想用Moq,但是好像不太可能?这是我到目前为止的测试内容:namespace TestingReactDotNetTests{    public class DayTodayTests    {        [Test]        public void ReturnsDateAndTime()        {            var controller = new DayTodayController();            string result = controller.GetDate();            string expected = "Today is Tuesday 27 August 2019 and the time is 10:00";            Assert.AreEqual(expected, result);         }    }}我的问题是 - 如何设置日期和时间,以便DateTime.Now在字符串中调用时,它不是当前的日期和时间?
查看完整描述

1 回答

?
慕村225694

TA贡献1880条经验 获得超4个赞

实现此目的的常用方法是在您正在测试的对象的构造函数中注入日期/时间提供程序。例如:


public interface IDateTimeProvider

{

    DateTime Now();

}

以及该接口的具体实现:


public class DateTimeProvider : IDateTimeProvider

{

    public DateTime Now() 

    {

        return Datetime.Now;

    }

}

您需要添加IDateTimeProvider到 DI 容器中,


就像是


services.AddSingleton<IDateTimeProvider, DateTimeProvider>(); 

但这取决于你如何设置它,你正在使用哪个框架等。


您的控制器将更改为如下所示:


[Route ("api/[controller]")]

public class DayTodayController : Controller

{

    private readonly IDateTimeProvider _dateTimeProvider;


    public DayTodayController(IDateTimeProvider dateTimeProvider)

    {

        _dateTimeProvider = dateTimeProvider;

    }


    [HttpGet, Route ("GetDate")]

    public  string GetDate () {

        var dateTime = _dateTimeProvider.Now();

        var info = $"Today is {dateTime.ToString("dddd, dd MMMM yyyy")} and the time is {dateTime.ToString("hh:mm tt")}";

        return info;

    }

}

请注意将日期时间分配给变量。多次调用DateTime.Now将给出不同的值,因此您需要对一个实例进行操作以获得所需的行为。


现在您可以使用该接口的非脆弱模拟实现进行测试:


public class DayTodayTests

{

    [Test]

    public void ReturnsDateAndTime()

    {

        //Arrange

        var mockedDateTimeProvider = new Mock<IDateTimeProvider>();

        mockedDateTimeProvider.Setup(dtp => dtp.Now()).Returns(new DateTime(2019, 8, 27, 10, 0, 0));

        var controller = new DayTodayController(mockedDateTimeProvider.Object);


        //Act

        string result = controller.GetDate();


        //Assert

        string expected = "Today is Tuesday 27 August 2019 and the time is 10:00 AM";


        Assert.AreEqual(expected, result); 

    }

}


查看完整回答
反对 回复 2023-09-24
  • 1 回答
  • 0 关注
  • 84 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信