gpt4 book ai didi

unit-testing - 单元测试抽象类和/或接口(interface)

转载 作者:行者123 更新时间:2023-12-04 08:16:45 25 4
gpt4 key购买 nike

我正在尝试在 Visual Studio 2010 中的当前项目上开始使用单元测试。但是,我的类结构包含许多接口(interface)和抽象类继承关系。

如果两个类派生自同一个抽象类或接口(interface),我希望能够在它们之间共享测试代码。我不确定该怎么做。我在想我为要测试的每个接口(interface)创建一个测试类,但我不确定将具体类提供给适用的单元测试的正确方法。

更新

好的,这是一个例子。假设我有一个接口(interface) IEmployee ,它由抽象类 Employee 实现,然后由两个具体类 Worker 和 Employee 继承。 (代码如下所示)

现在假设我想创建适用于所有 IEmployee 或员工的测试。或者,为特定类型的员工创建特定测试。例如,我可能想要断言,对于任何 IEmployee 的实现,将 IEmployee.Number 设置为小于零的数字都会引发异常。我更愿意从任何 IEmployee 的角度编写测试,然后能够在 IEmployee 的任何实现上使用这些测试。

这是另一个例子。我可能还想断言,将任何员工的休假时间设置为小于零的值会引发错误。然而,我可能还希望有不同的测试适用于特定的具体版本的 Employee。假设我想测试 Worker 如果提供超过 14 天的假期会引发异常,但可以为经理提供最多 36 天的假期。

public interface IEmployee
{
string Name {get; set;}
int Number {get; set;}
}


public abstract class Employee:IEmploee
{
string Name {get; set;}
int Number {get;set;}
public abstract int VacationTime(get; set;)
}


public abstract class Worker:IEmployee
{
private int v;

private int vTime;
public abstract int VacationTime
{
get
{
return VTime;
}
set
{
if(value>36) throw new ArgumentException("Exceeded allowed vaction");
if(value<0)throw new ArgumentException("Vacation time must be >0");
vTime= value;
}
}


public void DoSomWork()
{
//Work
}
}


public abstract class Manager:IEmployee
{
public abstract int VacationTime
{
get
{
return VTime;
}
set
{
if(value>14) throw new ArgumentException("Exceeded allowed vaction");
if(value<0)throw new ArgumentException("Vacation time must be >0");
vTime= value;
}
}

public void DoSomeManaging()
{
//manage
}

}

所以我想我正在寻找的是一个允许我嵌套单元测试的工作流程。因此,例如,当我测试 Manager 类时,我想首先测试它是否通过了 Employee 和 IEmployee 测试,然后测试特定成员,例如 DoSomeManaging() .

最佳答案

我想我知道你的意思。我遇到过同样的问题。

我的解决方案是创建一个层次结构也用于测试。我将使用您展示的相同示例。

首先,为基础 IEmployee 提供一个抽象测试类。

它有两个主要内容:
一世。您想要的所有测试方法。
ii.返回 IEmployee 所需实例的抽象方法。

[TestClass()]
public abstract class IEmployeeTests
{
protected abstract GetIEmployeeInstance();

[TestMethod()]
public void TestMethod1()
{
IEmployee target = GetIEmployeeInstance();
// do your IEmployee test here
}

}

其次,您为 IEmployee 的每个实现都有一个测试类,实现抽象方法并提供适当的 IEmployee 实例。
[TestClass()]
public class WorkerTests : IEmployeeTests
{

protected override GetIEmployeeInstance()
{
return new Worker();
}

}

[TestClass()]
public class ManagerTests : IEmployeeTests
{

protected override GetIEmployeeInstance()
{
return new Manager();
}

}

您可以看到一切都按预期工作,并且 VS 为您在 TestView 窗口中为每个 WorkerTests 和 ManagerTests 类提供了预期的测试方法。
您可以运行它们并获得 IEmployee 接口(interface)的每个实现的测试结果,只需要在基 IEmployeeTests 类中创建测试。

您始终可以为派生的 WorkerTests 和 ManagerTests 类添加特定测试。

现在的问题是,实现多个接口(interface)的类怎么样,比如说 EmployedProgrammer?
public EmployedProgrammer : IEmployee, IProgrammer
{
}

我们在 C# 中没有多重继承,所以这不是一个选项:
[TestClass()]
public EmployedProgrammerIEmployeeTests : IEmployeeTests, IProgrammerTests
{
// this doesn't compile as IEmployeeTests, IProgrammerTests are classes, not interfaces
}

对于这种情况,解决方案是具有以下测试类:
[TestClass()]
public EmployedProgrammerIEmployeeTests : IEmployeeTests
{
protected override GetIEmployeeInstance()
{
return new EmployedProgrammer();
}
}

[TestClass()]
public EmployedProgrammerIProgrammerTests : IProgrammerTests
{
protected override GetIProgrammerInstance()
{
return new EmployedProgrammer();
}
}


[TestClass()]
public abstract class IProgrammerTests
{
protected abstract GetIProgrammerInstance();

[TestMethod()]
public void TestMethod1()
{
IProgrammer target = GetIProgrammerInstance();
// do your IProgrammerTest test here
}

}

我用这个效果很好。
希望能帮助到你。

问候,
何塞

关于unit-testing - 单元测试抽象类和/或接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3731216/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com