【问题标题】:Unit test approach for generic classes/methods通用类/方法的单元测试方法
【发布时间】:2010-07-02 22:23:35
【问题描述】:

什么是覆盖泛型类/方法的单元测试的推荐方法?

例如(参考我下面的示例代码)。是否会有 2 或 3 倍的测试来覆盖使用几种不同类型的 TKey、TNode 类来测试方法?还是仅仅一节课就够了?

public class TopologyBase<TKey, TNode, TRelationship> 
    where TNode : NodeBase<TKey>, new() 
    where TRelationship : RelationshipBase<TKey>, new()

{
    // Properties
    public Dictionary<TKey, NodeBase<TKey>> Nodes { get; private set; }
    public List<RelationshipBase<TKey>> Relationships { get; private set; }

    // Constructors
    protected TopologyBase()
    {
        Nodes = new Dictionary<TKey, NodeBase<TKey>>();
        Relationships = new List<RelationshipBase<TKey>>();
    }

    // Methods
    public TNode CreateNode(TKey key)
    {
        var node = new TNode {Key = key};
        Nodes.Add(node.Key, node);
        return node;
    }

    public void CreateRelationship(NodeBase<TKey> parent, NodeBase<TKey> child) {
    .
    .
    .

【问题讨论】:

  • 我只是想问同样类型的问题。

标签: c# .net unit-testing generics


【解决方案1】:

我通常为测试目的创建一个 DummyClass 作为通用参数传递(在您的情况下,您应该创建 3 个类)并且我测试该类 (TopologyBase) 一次。

使用不同的泛型类型进行测试没有意义,因为泛型类型不应破坏 TopologyBase 类。

【讨论】:

  • 因此,您将创建一个专门用于测试泛型类的新类,而不是创建一个说 Integer 的泛型类。您会在新类中添加任何功能吗?
  • 没错。不,新类应该是一个什么都不做的 Dummy。
【解决方案2】:

这可能真的取决于您的代码,但至少有两件事需要考虑:

  • Private / Public:如果您的实现使用或将来可能使用反射或 DLR(直接或通过 C# 中的 dynamic 关键字)进行某些操作,您应该使用至少一种在实现程序集中不可见的类型进行测试。
  • ValueType / ReferenceType :在某些情况下可能需要测试它们之间的差异,例如
    • 对值类型(如 ToString 或 Equals)调用 Object 方法始终是正确的,但对于引用则不正确,因为它们可能为 null。
    • 如果您正在进行性能测试,传递值类型可能会产生后果,尤其是当它们很大时(不应该发生,但在指导方针和现实之间有时会有一个小的差距...)

【讨论】:

    【解决方案3】:

    您可以使用模拟框架来验证您的类和泛型类型之间的预期交互。我为此使用Rhino Mocks

    【讨论】:

      【解决方案4】:

      要对开放生产类型进行单元测试,请创建从开放类型派生的测试代码类型 - 然后测试该类型。

      public class TestingTopologyBase : TopologyBase<KeyType, NodeType, RelationshipType> ...
      

      在 TestingTopologyBase 类中,提供任何抽象方法或任何其他必需的基本实现。

      这些 Testing[ProductionType] 实现通常是您的单元测试代码感知被测泛型类型实际在做什么的好地方。例如,您可以将信息存储起来,以后可以供单元测试代码使用,以检查测试期间发生的情况。

      然后在您的单元测试方法中,创建 TestingTopologyBase 类的实例。这样,您就可以将泛型类型与派生自它的任何生产类型隔离开来进行测试。

      例子:

      [TestClass]
      public class TopologyBaseFixture {
      
          [TestMethod]
          public void SomeTestMethod() {
             var foo = new TestingTopologyBase(...);
             ...test foo here
      

      【讨论】:

        【解决方案5】:

        很大程度上取决于您的通用约束。如果一个或多个类型参数需要接口或基类约束,则现在存在对接口契约的依赖。由于你的类的逻辑可能部分依赖于实现接口的类的行为,你可能需要以各种方式模拟接口来练习你的所有逻辑路径。例如,如果您有 T: IEquatable&lt;T&gt;,则需要使用具有有意义的相等行为的类型,例如 int。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-08-29
          • 1970-01-01
          • 1970-01-01
          • 2019-02-03
          • 2017-12-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多