使用It.IsAny <datetime>()的Moq单元测试失败</datetime>

时间:2011-03-28 14:34:25

标签: c# moq

我正在使用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上发表评论,那么测试就会通过,而不会对我的测试进行任何其他更改。另外,如果我将TimeStartedTimeStopped的要求从new DateTime(1900, 1, 1)更改为It.IsAny<DateTime>(),则测试失败。我在单元测试之外使用实际实现而不是模拟存储库运行测试代码,并且正确地为TimeQueued分配了它的值。知道为什么It.IsAny似乎不适用于DateTime属性,或者我是否错误地设置了我的期望?

更新:我在其他测试中使用It.IsAny()没有任何问题,但是这个测试仍然失败。我想这可能是因为这是在It.Is lambda表达式中,但我不知道如何解决这个问题。

1 个答案:

答案 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分钟和最大边界之间。