为什么不只使用DateTime.Now? [英] Why not just use DateTime.Now?
问题描述
我最近一直在尝试了解界面.
I have been trying to learn about interfaces recently.
我看到了这段代码,无法理解为什么您不仅仅使用 DateTime.Now
.我不确定界面为什么有用,有人可以解释一下吗?这本书的作者试图解释,但我真的不明白如何以他们所说的方式实现它:
I saw this piece of code and can't wrap my head around why you wouldn't just use DateTime.Now
on its own. I'm unsure why the interface is useful, can someone explain please? The author of the book tried to explain but I don't really understand how to implement it the way they are saying:
程序员在抽象的海洋中迷失了自己吗?你可能是倾向于这样想,但是实际上这很聪明.想像你必须在提供不同结果的类上运行一些测试取决于当前时间(或日期).这一点并不罕见;也许这是一个需要获取汇率的金融应用程序在给定的日期.因此,请尝试测试代码库是否具有DateTime.Now直接在方法中.使用INowResolver,您可以立即注入并测试昨天,现在和明天
Has the programmer lost himself in a sea of abstraction? You might be tempted to think so, but actually this is pretty smart. Imagine you have to run some tests on a class that gives different results dependent on the current time (or date). That’s not uncommon at all; maybe it’s a financial application that needs to get the exchange rate at a given date. So try testing that if the codebase has DateTime.Now directly in the methods. With the INowResolver you can inject your now and test for yesterday, now, and tomorrow
public interface INowResolver { DateTime GetNow(); }
public class NowResolver : INowResolver {
public DateTime GetNow() {
return DateTime.Now;
}
}
测试时,如果使用 NowResolver.GetNow
方法或仅使用 DateTime.Now
,结果将相同.
When I tested it the result was the same if I used the NowResolver.GetNow
method or just used DateTime.Now
.
测试:
NowResolver now = new NowResolver();
Console.WriteLine(now.GetNow());
Console.WriteLine(DateTime.Now);
System.Threading.Thread.Sleep(1000);
Console.WriteLine(now.GetNow());
Console.WriteLine(DateTime.Now);
输出:
07/02/2019 15:14:56
07/02/2019 15:14:56
07/02/2019 15:14:57
07/02/2019 15:14:57
推荐答案
编写单元测试时,每次运行它们时,以完全相同的方式执行测试很重要.
When you are writing unit tests, it is important that the tests execute in exactly the same way, every time you run them.
如果您的测试(或正在测试的代码)使用 DateTime.Now
(或 DateTime.UtcNow
),则每次运行时,您都会得到不同的测试结果(假设您正在测试包含上述 DateTime
)的属性.
If your test (or code being tested) uses DateTime.Now
(or DateTime.UtcNow
), then every time it runs you will get a different test result (assuming you are testing the property that contains said DateTime
).
如果将 DateTime
提取到一个接口中,则可以进行设置,以便在运行测试时,它总是在调用 INowResolver.Now
时返回相同的时间.
If you abstract away DateTime
into an interface, you can make it so that when your test runs, it always returns the same time when INowResolver.Now
is called.
示例:在此测试中,时间始终为2018年1月1日.
public class MyTest
{
public class TestNow : INowResolver
{
public DateTime Now {get;set;}
public DateTime GetNow() => Now;
}
[Test]
public void MyTest()
{
var resolver = new TestNow { Now = new DateTime(2018,1,1) }
var testClass = new TestClass(resolver);
}
}
实际上,如果在所有情况下我都使用此方法,则 Now
是一个属性,就像它在 DateTime.Now
中一样,而不是函数.
Actually, if all cases I've used this method, Now
is a property, just like it is in DateTime.Now
, not a function.
这篇关于为什么不只使用DateTime.Now?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!