简体   繁体   English

Foq Mock.Expect with Times> 1总是失败

[英]Foq Mock.Expect with Times > 1 always fails

None of the Mock.Expect examples I've found use Times other than 0 or 1 (never, once). 的无Mock.Expect例子我发现使用Times大于0或1(从来没有,一次)等。 I modifed one of the existing tests from Foq.Usage.fsx to attempt something that's not 0 or 1, but I can't make it work. 我修改了Foq.Usage.fsx中的一个现有测试来尝试不是0或1的东西,但我不能使它工作。

Does anyone see anything wrong? 有人看错了什么吗?

let [<Test>] ``expect method is called the specified number of times`` () =
    // Arrange
    let xs = Mock.Of<System.Collections.Generic.IList<int>>()
    // Assert (setup)
    Mock.Expect(<@ xs.Contains(0) @>, never)
    Mock.Expect(<@ xs.Contains(1) @>, once)
    Mock.Expect(<@ xs.Contains(2) @>, exactly 2)
    // Act
    xs.Contains(1) |> ignore
    xs.Contains(2) |> ignore
    xs.Contains(2) |> ignore
    // Assert
    verifyAll xs

This is a bug in Foq , when you use Mock.Expect it checks the expectations are met at the time of invocation on the mock. 这是Foq中的一个错误,当你使用Mock.Expect它检查在模拟调用时满足的期望。 If the given expectation is not met an exception is thrown. 如果未满足给定的期望,则抛出异常。 This may in theory be useful as it gives a stack trace at the exact point that an expectation is not met. 这在理论上可能是有用的,因为它在不满足期望的确切点处给出堆栈跟踪。

The issue with exactly 2 is that the expectation is checked first after one invocation and it is not exactly two. exactly 2的问题是在一次调用之后首先检查期望,而不是两次。 In effect at invocation time we want to interpret exactly 2 as at most two, and at verifyAll as exactly two. 实际上,在调用时,我们希望将exactly 2解释为最多两个,并将verifyAll精确verifyAll为两个。

You can get closer to the behaviour I believe you want with the existing implementation using Mock.Expect with atmost 2 and/or a plain old verify after the effect: 您可以使用Mock.Expect与现有实现更接近我认为您想要的行为,使用atmost 2和/或效果后的普通旧验证:

let [<Test>] ``expect method is called the specified number of times`` () =
    // Arrange
    let xs = Mock.Of<System.Collections.Generic.IList<int>>()
    // Assert (setup)
    Mock.Expect(<@ xs.Contains(0) @>, never)
    Mock.Expect(<@ xs.Contains(1) @>, once)
    Mock.Expect(<@ xs.Contains(2) @>, atmost 2)
    // Act
    xs.Contains(1) |> ignore
    xs.Contains(2) |> ignore
    xs.Contains(2) |> ignore
    // Assert
    Mock.Verify(<@ xs.Contains(2) @>, exactly 2)
    verifyAll xs

Thanks for reporting the issue. 感谢您报告此问题。 The issue is now fixed in the source and will be available in the next release. 该问题现已在源代码中修复,并将在下一版本中提供。

As discussed in the comments, this doesn't answer your question but ... I'd write this (which works): 正如评论中所讨论的,这不能回答你的问题,但是......我会写这个(有效):

let xs = Mock.Of<System.Collections.Generic.IList<_>>()
// Act
xs.Contains(1) |> ignore
xs.Contains(2) |> ignore
xs.Contains(2) |> ignore
// Assert
verify <@ xs.Contains(0) @> never
verify <@ xs.Contains(1) @> once
verify <@ xs.Contains(2) @> <| exactly 2

Thank you, Ruben. 谢谢你,鲁本。 I agree, the explicit verify s are best, but (also on your suggestion) the code below works in case anyone would want to use Expect / verifyAll . 我同意,显式verify是最好的,但(也在您的建议下)下面的代码适用于任何人想要使用Expect / verifyAll

let [<Test>] ``expect method is called the specified number of times`` () =
    // Arrange
    let xs = Mock.Of<System.Collections.Generic.IList<int>>()
    // Act
    xs.Contains(1) |> ignore
    xs.Contains(2) |> ignore
    xs.Contains(2) |> ignore
    // Assert
    Mock.Expect(<@ xs.Contains(0) @>, never)
    Mock.Expect(<@ xs.Contains(1) @>, once)
    Mock.Expect(<@ xs.Contains(2) @>, exactly 2)
    verifyAll xs

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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