我正在使用Moq为项目编写单元测试,当我尝试验证DateTime属性是否被赋值时,其中一个测试失败。这是我的验证(失败):
_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());
如果我在task_queue.TimeQueued
上发表评论,那么测试就会通过,而不会对我的测试进行任何其他更改。另外,如果我将TimeStarted
或TimeStopped
的要求从new DateTime(1900, 1, 1)
更改为It.IsAny<DateTime>()
,则测试失败。我在单元测试之外使用实际实现而不是模拟存储库运行测试代码,并且正确地为TimeQueued
分配了它的值。知道为什么It.IsAny
似乎不适用于DateTime
属性,或者我是否错误地设置了我的期望?
更新:我在其他测试中使用It.IsAny()没有任何问题,但是这个测试仍然失败。我想这可能是因为这是在It.Is lambda表达式中,但我不知道如何解决这个问题。
答案 0 :(得分:7)
我确信必须在mock对象的范围内使用It.IsAny<>()
语法。在这种情况下,直接使用Setup
和模拟参数。这是因为模拟对象处于记录模式,捕获您传递给参数的值,所以
mock.Setup(x => x.Foo(It.IsAny<Bar>()));
将在执行“设置”行时处理参数。
但是在您的示例中,您尝试使用委托中的It.IsAny<>()
来验证匹配中传递的参数。当发生这种情况时,模拟器不会记录,而是在被测对象(后来更晚)的使用过程中。
所以someValue == It.IsAny<DateTime>()
无法求值为true,因为IsAny
方法的返回必须返回匹配值才能为true。我希望It.IsAny<int>()
也不起作用。
我的建议是,您必须匹配精确值,或者在这种情况下匹配一系列日期
&& IsInRange(DateTime.MinValue, DateTime.MaxValue, task_queue.TimeQueued)
其中IsInRange
只是另一种检查值的方法是在2分钟和最大边界之间。