I'm using Moq to write the unit tests for a project, and one of the tests is failing when I try to verify that a DateTime property is assigned a value. Here's my Verify (which fails):
_mockTaskContext.Verify(context => context.TaskQueue.AddObject(It.Is<TaskQueueItem>(
task_queue => task_queue.TaskCode == (int)TaskCode.MyTask
&& task_queue.ClientID == ExpectedClientID
&& task_queue.JobNumber == It.IsAny<int>()
&& task_queue.Requester == String.Empty
&& task_queue.JobStatus == (int)JobStatus.Submitted
&& task_queue.TimeQueued == It.IsAny<DateTime>()
&& task_queue.TimeStarted == new DateTime(1900, 1, 1)
&& task_queue.TimeStopped == new DateTime(1900, 1, 1)
&& task_queue.TaskParameters == expectedTaskParam
)), Times.Once());
If I comment out the expectation on task_queue.TimeQueued
then the test passes, without making any other changes to my test. Also, if I change the requiremen开发者_开发问答t on either TimeStarted
or TimeStopped
from new DateTime(1900, 1, 1)
to It.IsAny<DateTime>()
, the test fails. I've run the code under test outside the unit test with the actual implementation instead of a mocked repository, and TimeQueued
is being assigned its value correctly. Any idea why It.IsAny
doesn't seem to work correctly for DateTime
properties, or am I setting up my expectations incorrectly?
Update: I'm using It.IsAny() in other tests without any problem, but this test is still failing. I think it might be because this is inside the It.Is lambda expression, but I don't know how I would work around that.
I am sure the It.IsAny<>()
syntax must be used within the scope of the mock object. In this case when you use Setup
and the mock arguments directly. This is because the mock object is in recording mode capturing the values you pass into arguments so
mock.Setup(x => x.Foo(It.IsAny<Bar>()));
will process the arguments when the Setup line is executed.
However in your example you are trying to use It.IsAny<>()
from within the delegate to verify an argument passed in matches. When this occurs the mock is not recording but in the process of being used as a result of the object under test (which is much later).
So someValue == It.IsAny<DateTime>()
cannot evaluate to true as the return of the IsAny
method must return a matching value for it to be true. I expect that It.IsAny<int>()
also does not work.
My suggestion is that you will have to match either exact values or in this case match a range of dates
&& IsInRange(DateTime.MinValue, DateTime.MaxValue, task_queue.TimeQueued)
where IsInRange
simply another method you have for checking a value is between 2 min and max bounds.
精彩评论