代码之家  ›  专栏  ›  技术社区  ›  trendl

单元测试继承

  •  10
  • trendl  · 技术社区  · 16 年前

    我有一个关于单元测试的问题。假设我有几个类继承了父类的行为。我不想测试所有的儿童班的这种行为。相反,我将测试父类。但是,我也应该提供一个测试来证明这种行为在儿童班中是可用的。你认为像assert.isrue(new childclass()is parentclass)这样的东西有意义吗?

    7 回复  |  直到 10 年前
        1
  •  8
  •   joel.neely    16 年前

    如果您使用的是最先进的单元测试框架,我不理解这种说法

    我不想测试所有的儿童班的这种行为。

    如果将子类的一个实例交给您的单元测试(针对父类的一个实例编写),那么它们的工作应该是不变的。 假如 您的子类没有以破坏继承方法上的契约的方式重写父类行为的某些方面。这正是你需要测试的,不是吗?

    如果您担心运行测试所需的时间,我将再次检查以确保您的测试是分区的,这样您就可以根据正在积极工作的内容有选择地运行测试(但仍然定期运行完整的产品组合以捕获意外的依赖项)。

        2
  •  8
  •   tvanfosson    16 年前

    我认为写一个继承有效的测试是浪费时间。如果您尝试使用基类方法,编译器将检查这些方法是否可用,假设您不使用IntelliSense进行捕获。我可能会在一个子类中测试行为,然后只在修改行为的每个子类中(或者行为所依赖的某个状态)进行测试。

        3
  •  6
  •   Bwing    14 年前

    使您的测试继承自一个基类测试,大致类似于这样。

    public class MyBaseClass
    {
        public virtual void DoStuff() { }
        public virtual void DoOtherStuff() { }
    }
    
    public class MySubClass : MyBaseClass
    {
        public override void DoOtherStuff()
        {
            // different to to base
        }
    }
    
    public abstract class TestOfBaseClass
    {
        protected abstract MyBaseClass classUnderTest { get; }
    
        [TestMethod]
        public void TestDoStuff()
        {
            classUnderTest.DoStuff();
            Assert.StuffWasDone();
        }
    }
    
    [TestClass]
    public class WhenSubclassDoesStuff : TestOfBaseClass
    {
        protected override MyBaseClass classUnderTest
        {
            get { return new MySubClass(); }
        }
    
        [TestMethod]
        public void ShoudDoOtherStuff()
        {
            classUnderTest.DoOtherStuff();
            Assert.OtherStuffDone();
        }
    }
    

    大多数流行的测试框架在运行子类测试时都会在基本测试中运行测试方法。

    或者看看 https://github.com/gregoryyoung/grensesnitt

        4
  •  5
  •   Spence    16 年前

    你不想测试对象的类型, 除非 它来自一个非类型化的工厂方法。否则,您将针对C编译器编写一个单元测试,这不是您想要做的。

        5
  •  1
  •   Matthew    16 年前

    C编译器会为您处理这种检查。

    如果你喜欢,你可以写一些像:

    ParentClass childClass = new ChildClass()
    var testOutput = childClass.ParentMethod();
    Assert.IsNotNull(testOutput);
    
        6
  •  1
  •   MikeT    10 年前

    我认为你的测试结构应该反映你的对象结构 所以如果你有继承自类车的类车

    那么您应该有从类testVehicle继承的类testcar

    通过执行此测试,车辆将自动继承所有车辆测试的正确测试,这意味着如果在车辆中覆盖该功能,则很可能会破坏测试,突出显示需要在车辆中进行覆盖测试以支持新行为,如果测试未被破坏,则覆盖可能首先是多余的

    class Vehicle
    {
        public virtual bool LicenceRequired
        {
            get{throw new NotImplmentedException()
        }
    }
    class Bicycle:Vehicle
    {
        public override bool LicenceRequired
        {
            get{return false;}
        }
    }
    class Car:Vehicle
    {
        public override bool LicenceRequired
        {
            get{return true;}
        }
    }
    class TestVehicle
    {
        public virtual Void LicenceRequiredTest()
        {
            Try
            {
                LicenceRequired
                Assert.Fail();
            }
            Catch(){}
        }
    }
    class TestBicycle:TestVehicle
    {
        public override void LicenceRequiredTest()
        {
            Assert.IsFalse(LicenceRequired);
        }
    }
    class TestCar:TestVehicle
    {
        public override void LicenceRequiredTest()
        {
            Assert.IsTrue(LicenceRequired);
        }
    }
    

    注: 只应在测试继承的对象时使用继承,而不仅仅是因为要对10个不相关的对象执行相同的测试。如果您想这样做,我建议您使用一个静态助手类

        7
  •  0
  •   Michael Meadows    16 年前

    有两种方法可以用来测试 行为 基本类的:

    1. 创建基类的存根实现,并对存根进行单元测试。只测试公共方法。测试私有和受保护的方法是没有意义的,因为这些方法将被您应该在子类中测试的公共方法所消耗。这种方法不会强制您的基类实现没有错误地隐藏行为。
    2. 为练习基类方法的单元测试创建测试超类。无论何时测试基类的子类,都要让测试类从测试超类继承。这种方法确保您不会无意中更改基类的行为,但会限制测试的可伸缩性。

    不要费心验证继承是否真的有效(整个 Assert.IsTrue(new ChildClass() is ParentClass) 事情)。您应该只测试行为。这是.NET框架(继承)的一个结构特性,您应该相信它是有效的,否则您将发现自己处于检查框架特性的向下螺旋中。