Eri*_*tas 8 inheritance unit-testing interface visual-studio-2010
我正在尝试在Visual Studio 2010中的当前项目上开始使用单元测试.但是,我的类结构包含许多接口和抽象类继承关系.
如果两个类是从同一个抽象类或接口派生的,那么我希望能够在它们之间共享测试代码.我不确定该怎么做.我想我为每个要测试的接口创建了一个测试类,但我不确定将具体类提供给适用的单元测试的正确方法.
更新
好的,这是一个例子.假设我有一个接口IEmployee,它由一个抽象类Employee实现,然后由两个具体的类Worker和Employee继承.(代码如下)
现在说我想创建适用于所有IEmployees或Employees的测试.或者为特定类型的员工创建特定测试.例如,我可能想断言将IEmployee.Number设置为小于零的数字,因为任何IEmployee实现都会引发异常.我更喜欢从任何IEmployee的角度编写测试,然后能够在IEmployee的任何实现上使用测试.
这是另一个例子.我可能还想断言,将任何员工的休假时间设置为小于零的值和错误.然而,我可能还希望有不同的测试适用于特定的Employee特定版本.假设我想测试如果工作人员提供超过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
}
}
Run Code Online (Sandbox Code Playgroud)
所以我想我正在寻找的工作流程将允许我嵌套单元测试.因此,例如,当我测试Manager类时,我想首先测试它是否通过了Employee和IEmployee测试,然后测试特定的成员,例如DoSomeManaging()
.
小智 6
我想我知道你的意思.我遇到过同样的问题.
我的解决方案是创建一个用于测试的层次结构.我将使用您展示的相同示例.
首先,为基本IEmployee设置一个抽象测试类.
它有两个主要的东西:i.您想要的所有测试方法.II.一种抽象方法,返回IEmployee的所需实例.
[TestClass()]
public abstract class IEmployeeTests
{
protected abstract GetIEmployeeInstance();
[TestMethod()]
public void TestMethod1()
{
IEmployee target = GetIEmployeeInstance();
// do your IEmployee test here
}
}
Run Code Online (Sandbox Code Playgroud)
其次,您为IEmployee的每个实现都有一个测试类,实现抽象方法并提供适当的IEmployee实例.
[TestClass()]
public class WorkerTests : IEmployeeTests
{
protected override GetIEmployeeInstance()
{
return new Worker();
}
}
[TestClass()]
public class ManagerTests : IEmployeeTests
{
protected override GetIEmployeeInstance()
{
return new Manager();
}
}
Run Code Online (Sandbox Code Playgroud)
您可以看到所有内容都按预期工作,VS为TestView窗口中的每个WorkerTests和ManagerTests类提供了预期的测试方法.您可以运行它们并获得IEmployee接口的每个实现的测试结果,只需在基本IEmployeeTests类中创建测试.
您始终可以为派生的WorkerTests和ManagerTests类添加特定测试.
现在的问题是,实现多个接口的类怎么样,让我们说EmployedProgrammer?
public EmployedProgrammer : IEmployee, IProgrammer
{
}
Run Code Online (Sandbox Code Playgroud)
我们在C#中没有多重继承,所以这不是一个选项:
[TestClass()]
public EmployedProgrammerIEmployeeTests : IEmployeeTests, IProgrammerTests
{
// this doesn't compile as IEmployeeTests, IProgrammerTests are classes, not interfaces
}
Run Code Online (Sandbox Code Playgroud)
对于此方案,解决方案是具有以下测试类:
[TestClass()]
public EmployedProgrammerIEmployeeTests : IEmployeeTests
{
protected override GetIEmployeeInstance()
{
return new EmployedProgrammer();
}
}
[TestClass()]
public EmployedProgrammerIProgrammerTests : IProgrammerTests
{
protected override GetIProgrammerInstance()
{
return new EmployedProgrammer();
}
}
Run Code Online (Sandbox Code Playgroud)
同
[TestClass()]
public abstract class IProgrammerTests
{
protected abstract GetIProgrammerInstance();
[TestMethod()]
public void TestMethod1()
{
IProgrammer target = GetIProgrammerInstance();
// do your IProgrammerTest test here
}
}
Run Code Online (Sandbox Code Playgroud)
我用这个效果很好.希望能帮助到你.
问候,何塞