【问题标题】:Unit testing when generic type is needed需要泛型类型时的单元测试
【发布时间】:2019-02-07 12:47:35
【问题描述】:

我有以下问题。我想测试一个泛型类 MyClass。但是,我并不真正关心用于 T 的类型。 但是,当我在测试中创建 MyClass 的实例时,我需要指定 T 应该是什么。 我可以这样做:

var sut = new MyClass<Object>();

它当然有效,但是,我不喜欢专门放置 Object,因为它向阅读此测试的人暗示,可能 Object 类型在这里很重要。

我喜欢 AutoFixture 使用的方法,其中每个值都是使用 fixture.Create&lt;T&gt;() 创建的,因为它向读者表明该值并不重要。示例:

[Fact]
public void IntroductoryTest()
{
    // Arrange
    Fixture fixture = new Fixture();

    int expectedNumber = fixture.Create<int>();
    MyClass sut = fixture.Create<MyClass>();
    // Act
    int result = sut.Echo(expectedNumber);
    // Assert
    Assert.Equal(expectedNumber, result);
}

在上面的代码中,我们并不关心数字,因此我们使用 AutoFixture 作为对需要某个数字这一事实的抽象。

有没有类似的解决方案,但关于泛型类使用的类型?

类似:var sut = MyClass&lt;fixture.GenericType&gt;(); 我不在乎这里的实际类型是什么。再解释一下我的用例:我有用于注册 MyClass 的 AutoFac 模块。在我的测试中,我只想测试模块是否正确注册了 MyClass 。对于该注册,我不想指定某些用于 MyClass 的确切类型。它可以是任何一个。

【问题讨论】:

  • 如果您测试的类是泛型的并且您不需要该泛型,这强烈表明您的类需要进一步分解。为什么你必须指定一个你不需要的泛型!将你的类重构为 2 个类,一个需要泛型,一个不需要
  • 您能举例说明fixture.Create&lt;T&gt;()是如何使用的吗?
  • @Alexander 我编辑了我的问题
  • @Liam 不太可能,我的课程实际上是一个配置映射器。它需要 T 来指定配置的类型。我的测试并没有真正测试该类 - 它测试用于注册该类的 AutoFac 模块。

标签: c# unit-testing generics autofixture


【解决方案1】:

目前 AutoFixture 不支持非封闭的泛型类型激活,不太可能有一天会改变。

首先,这是由于 C# 语言本身支持非封闭泛型类型仅用于反射目的。如果不关闭特定T 的类型,就不能声明MyClass&lt;&gt; 类型的变量。因此,即使 AutoFixture 替换类型并为您激活实例,也很难处理结果 - 如果您的类型支持,您要么需要使用 object 类型的变量,要么依赖 covariance。这些选项看起来都不可用。

其次,任务本身非常困难,因为泛型类型可能有约束。有时约束可能会变得疯狂,例如有循环依赖:class MyClass&lt;T1, T2&gt; where T1 : T2 where T2 : IEnumerable&lt;T1&gt;AutoFixture.Idioms 库已经尝试为 GuardClauseAssertion 解决这个问题,但成功了 is average。此功能需要动态类型生成(顺便说一句,并非所有平台都支持)和非常高级的 Reflection.Emit API 使用,这使得它很难正确实现。

【讨论】:

  • 感谢有趣的帖子。学习新东西总是很好
【解决方案2】:

也许你可以定义一个基类型比如IBase,你所有的T类型都实现了IBase(Class1&lt;T&gt; where T : IBase)然后你可以说var sut = new MyClass&lt;IBase&gt;();

【讨论】:

  • 它并没有真正改变任何东西。 Object 或 IBase - 它们都是我在测试中必须提到的具体类型。我想要更多的抽象。我想通知测试我需要某种类型,但我不在乎将使用哪种类型。这正是 AutoFixture 所做的,但它与类型而不是实例相关。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-19
  • 1970-01-01
  • 1970-01-01
  • 2021-01-31
  • 2015-09-11
  • 2021-10-24
相关资源
最近更新 更多