gpt4 book ai didi

c# - 如何在单元测试中模拟 DateTime.Now?

转载 作者:太空狗 更新时间:2023-10-29 19:39:41 25 4
gpt4 key购买 nike

<分区>

通常的解决方案是将其隐藏在界面后面。

public class RecordService
{
private readonly ISystemTime systemTime;

public RecordService(ISystemTime systemTime)
{
this.systemTime = systemTime;
}

public void RouteRecord(Record record)
{
if (record.Created <
systemTime.CurrentTime().AddMonths(-2))
{
// process old record
}

// process the record
}
}

在单元测试中你可以使用模拟对象并决定返回什么

[TestClass]
public class When_old_record_is_processed
{
[TestMethod]
public void Then_it_is_moved_into_old_records_folder()
{
var systemTime = A.Fake<ISystemTime>();
A.CallTo( () => system.Time.CurrentTime())
.Returns(DateTime.Now.AddYears(-1));

var record = new Record(DateTime.Now);
var service = new RecordService(systemTime);

service.RouteRecord(record);

// Asserts...
}
}

我不喜欢为了获取当前时间而将另一个接口(interface)注入(inject)我的类。对于这么小的问题,感觉解决方案太重了。解决方案是使用具有公共(public)功能的静态类。

public static class SystemTime
{
public static Func<DateTime> Now = () => DateTime.Now;
}

现在我们可以移除 ISystemTime 注入(inject),RecordService 看起来像这样

public class RecordService
{
public void RouteRecord(Record record)
{
if (record.Created < SystemTime.Now.AddMonths(-2))
{
// process old record
}

// process the record
}
}

在单元测试中,我们可以同样轻松地模拟系统时间。

[TestClass]
public class When_old_record_is_processed
{
[TestMethod]
public void Then_it_is_moved_into_old_records_folder()
{
SystemTime.Now = () => DateTime.Now.AddYears(-1);
var record = new Record(DateTime.Now);
var service = new RecordService();

service.RouteRecord(record);

// Asserts...
}
}

当然这也有不利的一面。您正在使用公共(public)字段(太可怕了!)所以没有人会阻止您编写这样的代码。

public class RecordService
{
public void RouteRecord(Record record)
{
SystemTime.Now = () => DateTime.Now.AddYears(10);
}
}

另外,我认为教育开发人员比创建抽象来保护他们不犯任何错误要好。其他可能的问题与运行测试有关。如果您忘记将函数恢复到其原始状态,它可能会影响其他测试。这取决于单元测试运行器执行测试的方式。您可以使用相同的逻辑来模拟文件系统操作

public static class FileSystem
{
public static Action<string, string> MoveFile = File.Move;
}

在我看来,使用公共(public)函数实现这种功能(模拟时间、简单的文件系统操作)是完全可以接受的。它使代码更易于阅读,减少了依赖性,并且在单元测试中易于模拟。

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com