在测试中使用两个以上模拟时出现异常

Exception when using more than two mocks in a test

我正在使用 xUnit 2AutoFixture 为 .Net Core 2.2 项目编写测试。我在测试中需要三个 Mock 来满足被测系统的要求,而以前 AutoFixture 这样做没有问题。但是现在当我向测试签名添加两个以上的模拟时我得到一个异常。

[Theory]
[AutoData]
public void ContrivedTest(
   Mock<IDependencyOne> mockDependencyOne,
   Mock<IDependencyTwo> mockDependencyTwo)
{
    Assert.True(true);
}

将按预期工作,但是:

[Theory]
[AutoData]
public void ContrivedTest(
   Mock<IDependencyOne> mockDependencyOne,
   Mock<IDependencyTwo> mockDependencyTwo,
   Mock<IDependencyThree> mockDependencyThree)
{
    Assert.True(true);
}

引发以下异常:

---- System.Reflection.TargetInvocationException : Exception has been thrown by the target of an invocation.

-------- System.ArgumentOutOfRangeException : Specified argument was out of the range of valid values. Parameter name: value

最近在 AutoFixture Github 上提出了这个问题(几乎逐字逐句),但提供的答案是:

AutoData and InlineAutoData do not become aware of Moq when you just install the AutoFixture.AutoMoq package. Instead, you should create your own data attributes derived from the default ones, customize fixture with Moq support and use them

对我来说没有意义。为什么两个模拟工作而不是三个?创建我自己的数据属性有何帮助,以及我应该如何自定义具有最小起订量支持的夹具?

值得注意的是,我没有使用 AutoMoq,因为我过去从来不需要这样做。我可以在测试中轻松地自己更新模拟,并且我打算在需要它工作时使用它,但我很好奇为什么以前工作得很好的东西不再工作了:我一直在使用它吗?它只是碰巧成功了?

Autofixture 使用 round-robin 分配默认值,因此它在 3 个模拟上失败。这是关于 Autofixture 问题页面的解释。

The issue happens when AutoFixture tries to auto-assign properties to a newly created Mock object. The auto-generated DefaultValue property doesn't suits very well, so Moq fails. For the enum values AutoFixture uses the round-robin strategy, which explains why the case with 2 mocks works, while 3 mocks start to crash it.

您可以阅读 full comment here