使用It.IsAny< DateTime>()的Moq单元测试失败 [英] Moq unit test with It.IsAny<DateTime>() fails

查看:73
本文介绍了使用It.IsAny< DateTime>()的Moq单元测试失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Moq编写项目的单元测试,并且当我尝试验证是否为DateTime属性分配了值时,其中一个测试失败.这是我的验证(失败):

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());

如果我注释掉对task_queue.TimeQueued的期望,则测试将通过,而无需对测试进行任何其他更改.另外,如果我将TimeStartedTimeStopped上的要求从new DateTime(1900, 1, 1)更改为It.IsAny<DateTime>(),则测试将失败.我已经使用实际的实现而不是模拟的存储库在单元测试之外运行了测试下的代码,并且TimeQueued被正确分配了其值.知道为什么It.IsAny对于DateTime属性似乎无法正常工作,还是我的期望设置不正确?

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?

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

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.

推荐答案

我确定It.IsAny<>()语法必须在模拟对象的范围内使用.在这种情况下,当您直接使用Setup和模拟参数时.这是因为模拟对象处于记录模式,因此捕获了您传递到参数中的值,因此

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>()));

将在执行Setup行时处理参数.

will process the arguments when the Setup line is executed.

但是,在您的示例中,您尝试从委托中使用It.IsAny<>()来验证匹配项中传递的参数.发生这种情况时,模拟不是在记录而是在作为被测试对象的结果而使用(此过程要晚得多).

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

因此,someValue == It.IsAny<DateTime>()不能评估为true,因为IsAny方法的返回必须返回一个匹配值才能使其为true.我希望It.IsAny<int>()也不起作用.

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)

其中,IsInRange只是用于检查值的另一种方法是在2分钟和最大范围之间.

where IsInRange simply another method you have for checking a value is between 2 min and max bounds.

这篇关于使用It.IsAny&lt; DateTime&gt;()的Moq单元测试失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆