使用It.IsAny< DateTime>()的Moq单元测试失败 [英] Moq unit test with It.IsAny<DateTime>() fails
问题描述
我正在使用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
的期望,则测试将通过,而无需对测试进行任何其他更改.另外,如果我将TimeStarted
或TimeStopped
上的要求从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< DateTime>()的Moq单元测试失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!