I'm writing a Unit Test class in C# (.NET 4.5). In one of the tests I'm checking the values of various properties after an instance of our class FeedbackDao is constructed. On construction, the FeedbackDate property of FeedbackDao is set to DateTime.Now.
FeedbackDao feedbackDao = new FeedbackDao();
// a couple of lines go here then I set up this test:
Assert.IsTrue(feedbackDao.FeedbackDate.CompareTo(DateTime.Now) < 0);
My assumption is that feedbackDao.FeedbackDate should always be just a little earlier than the current time returned by DateTime.Now, even if it's only by a millisecond, and my IsTrue test should always pass, but sometimes it passes and sometimes it fails. When I add a message like this:
Assert.IsTrue(feedbackDao.FeedbackDate.CompareTo(DateTime.Now) < 0,
feedbackDao.FeedbackDate.CompareTo(DateTime.Now).ToString());
the message sometimes reads -1 (meaning that FeedbackDate is earlier than Now) and sometimes reads 0 (meaning that the DateTime instances are equal).
Why is FeedbackDate not always earlier than Now? And, if I can't trust that comparison, how can I write a rigorous test to check the value of FeedbackDate when FeedbackDao is constructed?
My assumption is that feedbackDao.FeebackDate should always be just a little earlier than the current time returned by DateTime.Now, even if it's only by a millisecond.
What makes you think that? That would suggest that 1000 calls would have to take at least 1 second which seems unlikely.
Add to that the fact that DateTime.Now only has a practical granularity of about 10-15ms IIRC, and very often if you call DateTime.Now twice in quick succession you'll get the same value twice.
For the purpose of testability - and clean expression of dependencies - I like to use a "clock" interface (IClock) which is always used to extract the current system time. You can then write a fake implementation to control time however you see fit.
Additionally, this assertion is flawed:
Assert.IsTrue(feedbackDao.FeebackDate.CompareTo(DateTime.Now) < 0,
feedbackDao.FeebackDate.CompareTo(DateTime.Now).ToString());
It's flawed because it evaluates DateTime.Now twice... so the value that it reports isn't necessarily the same one that it checks. It would be better as:
DateTime now = DateTime.Now;
Assert.IsTrue(feedbackDao.FeebackDate.CompareTo(now) < 0,
feedbackDao.FeebackDate.CompareTo(now).ToString());
Or even better:
DateTime now = DateTime.Now;
DateTime feedbackDate = feedbackDao.FeebackDate;
Assert.IsTrue(now < feedbackDate,
feedbackDate + " should be earlier than " + now);
Your test is not that useful as it is, you're asserting that the value is less than DateTime.Now but that does not mean it was correctly set to the expected value. If the date time is not initialized it will have the DateTime.MinValue and that value will always pass the test.
This test is as valid as testing for feedbackDao.FeebackDate.CompareTo(DateTime.Now) <= 0 and with that you would not have the problem that motivated you to write this question.
You need to extract the dependency on DateTime.Now or use a mocking framework that supports mocking DateTime.Now and assert that the value is initialized to the correct one. You can check Microsoft Moles, now renamed to Fakes in VS 2012, which is the only mocking framework that I know that is free (kind of for the latest version, since it ships with VS and don't know if it is available on the express editions) and that will let you replace a call to DateTime.Now.
Update:
Without resorting to a mocking framework you could improve your test by doing something like this:
var lowerBoundary = DateTime.Now;
var dao = new FeedbackDao();
var upperBoundary = DateTime.Now;
Assert.IsTrue(dao.Date >= lowerBoundary && dao.Date <= upperBoundary);
When unit testing, I consider DateTime.Now to be an external dependency, and thus something needing to be mocked. What I've done in the past when testing scenarios involving DateTime.Now, I've just passed a Func<DateTime> in via the constructor of the class, which allows me to mock DateTime.Now during testing.
I prefer this over Jon Skeet's suggestion of using something like an IClock interface to wrap around the DateTime properties, just because the last time I did this, I felt silly making a new interface and class to wrap around a single property. If you're going to need to test around more than one of the static DateTime properties, I definitely agree with the IClock suggestion.
For example,
public class Foo
{
private readonly Func<DateTime> timeStampProvider;
public Foo(Func<DateTime> timeStampProvider)
{
this.timeStampProvider = timeStampProvider;
}
public Foo() : this(() => DateTime.Now)
{
}
public bool CompareDate(DateTime comparisonDate)
{
// Get my timestamp
return comparisonDate > timeStampProvider();
}
}
Then, during testing,
var testFoo = new Foo(() => new DateTime(1, 1, 2010));
I generally use a mock data to validate my logic. I evolve my test scenarios around the mock data. As suggested by DBM.
Mock data is a set of known data that is generally static or configurable. Common practice is to have a XML file with all the test data and load them as and when required. I can give you an example in our Project.
Try
Assert.IsTrue(feedbackDao.FeebackDate.CompareTo(DateTime.Now) < 1);
Or
Assert.IsTrue(feedbackDao.FeebackDate - DateTime.Now < someMarginOfError);
Time is generally fairly granular - often 10's of milliseconds IIRC.
Depending on your system, DateTime.Now is not updated every millisecond or tick, it is only updated periodically. Typically 10 ms or so. See here: How frequent is DateTime.Now updated ? or is there a more precise API to get the current time?
DateTime.Now isn't 100% accurate. It increases by around 130 ms(from personal experience per tick). So it's verry likely that if your method is fast enough the date will be equal to datetime.now and not smaller.
If you want a 100% accurate timer you should use the StopWatch class.
Msdn link to stopwatch
Related
This question already has answers here:
Change system date programmatically
(9 answers)
Closed 1 year ago.
I have a continuous testing pipeline, where unit and integration tests must pass on PRs before code has been able to merge.
It’s been great at reducing bugs and stabilizing our codebase, but we have a problem with time.
On weekends, several applications that comprise this stack have explicit checks to not let new orders be submitted on weekends. Worse, several of these applications make use of DateTime.Now for these checks and can’t be mocked without a large refactor.
Is it possible within c# to issue a command within our tests that will update the “server time” so most of our tests can work?
Try this.
To wit, calling the WinAPI function SetSystemTime with the appropriate data structure.
Don't forget to return the server time to "correct"!
[Assuming, of course, your server is Windows, which you don't mention...]
Short answer is no. If you want to tweak around some basic interfaces you either need to setup your OS and change time before test runs (which can have very unpredictable results) OR mock it. It is actually very simple:
Instead of using DateTime.Now/UtcNow use your explicit version.
public interface IDateTimeManager
{
DateTime Now {get;}
}
anywhere in the code base:
var now = _dateTimeManager.Now;
In test setup:
var mockDateTimeManager = new Mock<IDateTimeManager>();
mockDateTimeManager.Setup(x=> x.Now).Returns(new DateTime(2000,1,1));
In di setup:
var container = new Container();
container.RegisterSingleton<IDateTimeManager>(mockDateTimeManager.Object);
If your is app separate executable/service, you can pass an argument which sets initial value of this manager:
myapp.exe --start-date "2000-01-01"
public interface IDateTimeManager
{
DateTime UtcNow { get; }
}
internal sealed class DateTimeManager : IDateTimeManager
{
private readonly DateTime _initialTime;
private readonly DateTime _initialOsTime;
public DateTime UtcNow => _initialTime + (DateTime.UtcNow - _initialOsTime);
public DateTimeManager(DateTime initialTime)
{
_initialTime = initialTime;
_initialOsTime = DateTime.UtcNow;
}
}
PS
Inversion of control is your best friend for those kind of situations.
I come to conclusion it is easier to just replace OS specific methods to my own interfaces, rather than hacking around test environments. For example all of File namespace is often mocked for the same reason in my projects. I can emulate any behavior this way.
I know that DateTime.UtcNow does not have a relatively high degree of precision (10-15 ms resolution).
This is a problem for me because in my log files, I want better resolution for the purposes of resolving race conditions.
The question is: how can I get the current date/time with a better precision than what DateTime.UtcNow offers?
The only solution which I've seen up till now has been this: https://stackoverflow.com/a/15008836/270348. Is that a suitable way to solve the problem?
You can use Stopwatch for more precise measurements of time. You can then have each log entry record the time from the start of the first operation. If it's important, you can record the DateTime of the first operation and therefore calculate the times of the rest, but it sounds like just having the ticks/nanoseconds since the start of the first operation is good enough for your purposes.
If you want to add tracing you could write your own ETW Trace Provider like here. Then you do not need to take care how the timing is fetched. The Windows Kernel will take care that the timing is accurate and the order of the events is correct.
If you do not want to write your own ETW Provider you can use EventSource which is available as Nuget Package which allows you to use it from .NET 4.0 as well. More infos has Vance Morrison on his blog.
When use ETW events then you get a powerful trace analyzer for free with the Windows Performance Toolkit. As added bonus you can do system wide profiling in all processes with minimal impact as well.
This allows you to selectively add call stacks for every event you write which can be invaluable when you want to track down who did call your Dispose method two times.
Do you really need a precise timer or what you really need is something that give a sort? For example:
static class AutoIncrement
{
private static long num;
public static long Current
{
get
{
return Interlocked.Increment(ref num);
}
}
}
Console.WriteLine(AutoIncrement.Current);
Console.WriteLine(AutoIncrement.Current);
Console.WriteLine(AutoIncrement.Current);
Console.WriteLine(AutoIncrement.Current);
Console.WriteLine(AutoIncrement.Current);
This is guaranteed to be unique, and to change every time, and to be sorted. Its precision is better than microsecond. Its precision is absolute on a single PC.
or if you really want Timestamps...
static class AutoIncrement
{
private static long lastDate;
public static DateTime Current
{
get
{
long lastDateOrig, lastDateNew;
do
{
lastDateOrig = lastDate;
lastDateNew = lastDateOrig + 1;
lastDateNew = Math.Max(DateTime.UtcNow.Ticks, lastDateNew);
}
while (Interlocked.CompareExchange(ref lastDate, lastDateNew, lastDateOrig) != lastDateOrig);
return new DateTime(lastDateNew, DateTimeKind.Utc);
}
}
}
DateTime ac = AutoIncrement.Current;
Console.WriteLine(CultureInfo.InvariantCulture, "{0} {1:yyyy/MM/dd HH:mm:ss.fffffff}", ac.Ticks, ac);
This last variant uses as a base DateTime.UtcNow, but each call if it isn't changed, it increments it by one.
I'm trying to get a handle on using the Noda Time framework by Jon Skeet (and others).
I'm trying to store the current now(Instant). Instant is created from a long ticks, but what is the current now count of Ticks?
Is it:
Instant now = new Instant(DateTime.Now.ToUniversalTime().Ticks);
And or?
Instant now = Instant.FromDateTimeUtc(DateTime.Now.ToUniversalTime());
Are they equivalent, am I even doing this right?
PS, if Jon answer's this - I'd like to propose an Instant.Now property.
PS2 I know the title contains a tag, but it wouldn't let me have a short "Instant.Now" title.
I did a bit of research and it seems that the NodaTime way is to get the now moment according to a clock.
If you want to get the current time using the system clock, just use SystemClock.Instance.GetCurrentInstant().
However, instead of using the SystemClock.Instance directly in your code, it's preferable that you inject an IClock dependency in your time-aware classes.
This will allow you to:
provide the class with SystemClock.Instance at runtime, so the code will use the correct time
supply a fake implementation of IClock during unit testing to allow you to tweak the time as needed in order to test various scenarios (like the passing of time). There's a NodaTime.Testing project that offers such a class, called FakeClock.
I find this very useful. I think having something like new Instant() or Instant.Now return the current time would make it easier to hardcode usages of SystemClock under the covers, therefore missing the testing advantage that NodaTime offers.
For more info on unit testing with NodaTime, see this link.
Regarding your code examples: they are not equivalent.
Instant.FromDateTimeUtc(DateTime.Now.ToUniversalTime()) will indeed give you the current instant in UTC.
new Instant(DateTime.Now.ToUniversalTime().Ticks) will give you a wrong date far in the future, because the BCL's DateTime.Ticks represents the number of ticks since 1/1/0001, and NodaTime's Instant.Ticks represents the number of ticks since 1/1/1970 (see the remark here).
SystemClock.Now returns the current time as an Instant value:
Instant now = SystemClock.Instance.Now;
But you may want to heed the remarks in the documentation for the IClock interface:
IClock is intended for use anywhere you need to have access to the current time. Although it's not strictly incorrect to call SystemClock.Instance.Now directly, in the same way as you might call UtcNow, it's strongly discouraged as a matter of style for production code. We recommend providing an instance of IClock to anything that needs it, which allows you to write tests using the stub clock in the NodaTime.Testing assembly (or your own implementation).
As a simple example, suppose you have a Logger class that needs the current time. Instead of accessing SystemClock directly, use an IClock instance that's supplied via its constructor:
public class Logger
{
private readonly IClock clock;
public Logger(IClock clock)
{
this.clock = clock;
}
public void Log(string message)
{
Instant timestamp = this.clock.Now;
// Now log the message with the timestamp...
}
}
When you instantiate a Logger in your production code, you can give it SystemClock.Instance. But in a unit test for the Logger class, you can give it a FakeClock.
After reading this blog entry : http://wekeroad.com/post/4069048840/when-should-a-method-be-a-property,
I'm wondering why Microsoft choose in C# :
DateTime aDt = DateTime.Now;
instead of
DateTime aDt = DateTime.Now();
Best practices say : Use a method when calling the member twice in succession produces different results
And DateTime.Now is perfect example of non-determistic method/property.
Do you know if there any reason for that design ?
Or if it's just a small mistake ?
I believe in CLR via C#, Jeffrey Richter mentions that DateTime.Now is a mistake.
The System.DateTime class has a readonly
Now property that returns the current date and time. Each time you query this
property, it will return a different value. This is a mistake, and Microsoft wishes that
they could fix the class by making Now a method instead of a property.
CLR via C# 3rd Edition - Page 243
It actually is deterministic; it's output is not random, but is based on something quite predictable.
The 'current time' changes all the time; so to be relatively "the same" with each call, that value must change so that every time it's called, it's returning the current time.
EDIT:
This just occurred to me: Of course, two subsequent calls to a property getter can return different results, if something changed the property value in the interim. Properties are not supposed to be Constants.
So, that's what happening (conceptually) with DateTime.Now; its value is being changed between subsequent calls to it.
According to MSDN you should use a property when something is a logical data member of the object:
http://msdn.microsoft.com/en-us/library/bzwdh01d%28VS.71%29.aspx#cpconpropertyusageguidelinesanchor1
The go on to list out the cases where a method would be more appropriate. What is ironic is that one of the rules for a method is to use it when successive calls may return different results and of course Now certainly meets that criteria.
Personally I think this was done to eliminate the needs for the extra (), but I have found the absence of () confusing; it took me a little while to shift from the old approach in VB/VBA.
Guidelines are just that, not hard and fast rules.
Those guidelines are intended for stateful objects, and in reality are trying to say that properties should not mutate an object. DateTime.Now is a static property, so calling it does not mutate an object. It's also merely reflecting the natural state of time, not changing anything. It is simply observing a constantly changing timer.
So the point is, don't create properties that change the state of the object. Do create properties that merely observe the state of the object (even if the state changes externally).
As another example, let's look at the length of a string. This is a property, but the length of the string can change from invocation to invocation if something else changes the string externally. That's basically what is going on, the timer is being changed externally, Now just reflects its current state just as string.Length or any other such property.
In deciding "method versus property", a suggested test is "will successive calls return different results". I would suggest that a better test is the similar, but not identical question, "will calling the routine affect the outcome of future calls to the same or different routines?" In most cases, the answers to both the questions will be the same, since by far the most common reason that later calls to a routine will yield different results from the former one would be that the former one caused the later call to return a different result than it otherwise would have.
In the case of DateTime.Now, the only way in which one call would affect the value returned by another would be if the execution time taken by the first call caused the second call to occur measurably later than it otherwise would have. While a pedant might consider the passage of time to be a state-altering side effect of the first call, I would suggest that there are many properties which take longer to execute than DateTime.Now, and thus a call to any of those would have a greater likelihood of changing the value returned by a subsequent DateTime.Now call.
Note that if the "get time" routine were a virtual class member rather than being a static member, that would shift the balance in favor of making it a method; while the "expected" implementation would not affect the state of any object, it would be likely--or at least plausible--that some implementations might have side-effects. For example, calling Now on a RemoteTimeServer object might attempt to get the time from a remote server, and such attempt might have considerable side-effects on the rest of the system (e.g. by causing one or more machines to cache DNS/IP routing information, such that the next attempt to access the same server will complete 100ms faster).
Since there are no brightline rules on when to use a method and a property, DateTime.Now is truly just reading an exposed property of the state of the server, it may be constantly changing, but DateTime.Now never effects the state of any property, object or what not, so it is a property in the Framework.
I currently have the following method:
public void SetNewRandomValue() {
double newValue = numberGenerator.GenerateDouble(
genesValuesInterval.MinimumValue,
genesValuesInterval.MaximumValue
);
this.value = newValue;
}
What should be the guidelines for deciding how many tests (and which tests) to make to this method? I currently have done the following one (only after implementing the method -- that is, not test-first):
var interval = new Interval(-10, 10);
var numberGeneratorMock = new Mock<INumberGenerator>(MockBehavior.Strict);
var numberGenerator = numberGeneratorMock.Object;
double expectedValue = 5.0;
numberGeneratorMock.Setup(ng =>
ng.GenerateDouble(interval.MinimumValue, interval.MaximumValue))
.Returns(expectedValue);
var gene = new Gene(numberGenerator, 0, new Interval(-10, 10));
gene.SetNewRandomValue();
Assert.AreEqual<double>(expectedValue, gene.Value);
that basically just tests one situation. Regression-testingwise I'd say that I can't think of a way of messing up the code, turning it into mal functioning code and still have the test pass, that is, I think the method looks decently covered.
What are your opinions on this? How would you handle this little method?
Thanks
I would examine the code coverage with whatever testing tool you use, if a code coverage is available for your testing framework.
I personally like to work with either Microsoft Testing Tool or NUnit Testing Framework. I can then right-click my tests project and Test with NCover (while using NUnit), which will run the tests and tell me the percentage of code covered for each of my objects and tests.
I say that when you'll be done checking the code coverage which would result of at least a 98% code coverage, your code is likely to be well tested.
I'd recommend taking a look at Pex - it can really help generate the kind of unit tests you're looking for (i.e. figure out the different potential paths and results given a method and return value).
That test looks fine. The only thing you can actually assert about SetNewRandomValue is that the Value member is assigned afterward. You've mocked out the call to GenerateDouble and verified that Value contains the expected number, so you should be good.
You could also write a test to document (and verify) the expected behavior of Gene.SetNewRandomValue when NumberGenerator.GenerateDouble returns a value outside the specified interval.
You could definitely make a case for not unit testing this. IMHO, code inspection is a perfectly valid test methodology. You generally don't test things like property setters/getters, I think this method is simple enough to avoid unit testing for the same reason.
That said, if you really do want to test it, here's what I'd do: I'd test it with a couple values, not just once with 5. (SetNewRandomValue could be implemented as this.value = 5;, which should not pass.) I'd test it with a non-integer number, to confirm there's not a oddball cast to integer in there.
You could test that it's calling GenerateDouble with the proper parameters, though that's really testing an implementation detail. (SetNewRandomValue could be implemented as numberGenerator.GenerateDouble(0, interval.max - interval.min) + interval.min;, and that shouldn't fail the test.) You could use a real random number generator, and do SetNewRandomValue a few thousand times, and test that the values are evenly distributed in your expected range.
The method is doing three things:
Calling numberGenerator.GenerateDouble with genesValuesInterval.MinimumValue as the first parameter,
and with genesValuesInterval.MaximumValue as the second parameter,
and setting this.value to the result of that call.
Your test tests the third of these things, but not the first two. You could write two more tests that check the mock is called with the correct first and second parameters.
Edit (responding to comments below):
If the intended behaviour of this method is to set this.value to a random double within a previously specified range, then the above three tests are useful (assuming genesValuesInterval min and max are the previously specified range and that you have tests in place to assert that numberGenerator.GenerateDouble(min, max) returns a double within the specified range.
If the intended behaviour of this method is just to set this.value to a random double within (Double.MinValue, Double.MaxValue), then the first two tests are unnecessary as this is just an implementation detail.
If the inted
To answer how to test it, you should be able to describe what is the desired behavior.
Looking at your code, I assume that "Gene.SetNewRandomValue" is supposed to set self.Value to a number which falls within the Interval passed to the constructor.
I'm not super familiar with the Mock class, so I may be off base, but it appears that you are not testing that. What if your implementation had this typo?
double newValue = numberGenerator.GenerateDouble(
genesValuesInterval.MinimumValue,
genesValuesInterval.MinimumValue
);
Wouldn't your test still pass?