【问题标题】:Exception when using more than two mocks in a test在测试中使用两个以上模拟时出现异常
【发布时间】:2019-11-21 12:36:25
【问题描述】:

我正在使用 xUnit 2AutoFixture 为 .Net Core 2.2 项目编写测试。我在测试中需要三个 Mocks 来满足被测系统,而以前 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 : 调用目标抛出异常。

-------- System.ArgumentOutOfRangeException : 指定的参数超出了有效值的范围。参数名称:值

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

当您仅安装 AutoFixture.AutoMoq 包时,AutoData 和 InlineAutoData 不会意识到 Moq。相反,您应该创建自己的从默认属性派生的数据属性,使用 Moq 支持自定义夹具并使用它们

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

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

【问题讨论】:

    标签: c# unit-testing moq xunit autofixture


    【解决方案1】:

    Autofixture 使用循环分配默认值,因此它在 3 个模拟上失败。这是关于 Autofixture 问题页面的说明。

    当 AutoFixture 尝试将属性自动分配给 一个新创建的 Mock 对象。自动生成的 DefaultValue 属性 不太适合,因此 Moq 失败。对于枚举值 AutoFixture 使用循环策略,这就解释了为什么用 2 的情况 模拟工作,而 3 模拟开始崩溃。

    您可以阅读full comment here

    【讨论】:

    • 这是一个更清晰的解释,我不知道我以前怎么没找到它 - 可能在我的搜索结果中没有看到树木的木材 - 尽管它仍然不明显 为什么 以前可以用,现在不行了。我认为他们改变了策略,这就是问题所在。我想我会坚持更新模拟,因为尽管 Mark Seeman 提出的自定义属性有效,但我真的不想在每个测试项目中都有一个自定义属性,或者必须想一个共同的地方来放置它它可以在哪里使用,而不是被某人遗忘和维护。谢谢
    • 更可取的方式确实取决于项目中 AutoFixture 集成的水平。在我从事的大多数项目中,我们从第一天起就深入集成了 AutoFixture,因此从不使用默认的 AutoData。相反,我们同意始终使用我们自己的属性来避免混淆。这不仅提供了全局自定义 AutoFixture 的灵活性,而且还确保所有测试都是一致的并且看起来相似。无论如何,如果您最终更愿意坚持使用AutoData,还要注意NoAutoProperties 属性,这也可能有助于解决问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-13
    • 2011-08-22
    • 2018-12-11
    • 2021-12-30
    • 2015-11-20
    • 1970-01-01
    相关资源
    最近更新 更多