简体   繁体   中英

Moq unit test with It.IsAny<DateTime>() fails

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 requirement 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM