我已经实现了基于数组的堆栈数据结构以及相应的单元测试。这个Stack实现了我的IStack接口。所以目前,我的UT课程看起来像这样:
[TestClass]
public class Stack_ArrayBased_Tests
{
//check against empty collection
[TestMethod]
public void IsEmpty_NoElements()
{
var myStack = new Stack_ArrayBased_Example1(10);
var exp = true;
var act = myStack.IsEmpty();
Assert.AreEqual(exp, act);
}
现在,我即将实现基于链接列表的Stack。此Stack将继承自相同的IStack接口。
我想单独测试链表Stack。由于两者都是从相同的接口继承,我应该能够利用已经实现的单元测试,以防止不必要的代码重复。
创建两个单独的Unit Test类的最佳方法是什么,一个用于基于Array的Stack,另一个用于基于Linked List的Stack,它们将使用相同的Unit Test方法?我假设依赖注入将是一个答案,但我将如何去做呢?
答案 0 :(得分:5)
在测试方面,依赖注入永远不是解决方案。
你没有测试抽象,这是不可能的,你测试具体的实现。但是,您可以模拟抽象,接口和抽象类。
您可以创建一些类,其唯一目的是重用代码,然后从测试方法中调用该类,这样就可以了,并且完全可行。
对于每个具体实现,您仍然需要两个测试类,并且都要调用您创建的这个新类。这可以避免代码重复。
答案 1 :(得分:1)
您可以在另一种方法中分离逻辑。
[TestMethod]
public void IsEmpty_NoElements_ArrayBased()
{
var myStack = new Stack_ArrayBased_Example1(10);
IsEmpty_NoElements(myStack)
}
[TestMethod]
public void IsEmpty_NoElements_LinkedListBased()
{
var myStack = new Stack_LinkedListBased_Example1(10);
IsEmpty_NoElements(myStack)
}
public void IsEmpty_NoElements(IStack myStack)
{
var exp = true;
var act = myStack.IsEmpty();
Assert.AreEqual(exp, act);
}
答案 2 :(得分:1)
说我们有以下
public interface IStack
{
bool IsEmpty { get; }
}
public class StackImpl1 : IStack
{
public StackImpl1(int size)
{
IsEmpty = true;
}
public bool IsEmpty { get; }
}
public class StackImpl2 : IStack
{
public StackImpl2(int size)
{
IsEmpty = true;
}
public bool IsEmpty { get; }
}
我们希望从OP实施IsEmpty_OnCreation()
测试。我们可以进行常见测试并添加多个调用者(每个实现要测试一个)。问题在于扩展。
对于要测试的每个新功能,我们需要添加
1)测试实施对于我们介绍的每个新实现,我们需要为每个现有测试添加一个调用程序。
可以使用继承为我们完成大部分工作
public abstract class StackTest
{
protected abstract IStack Create(int size);
[TestMethod]
public void IsEmpty_NoElements()
{
var myStack = Create(10);
var exp = true;
var act = myStack.IsEmpty;
Assert.AreEqual(exp, act);
}
}
[TestClass]
public class StackImp1Fixture : StackTest
{
protected override IStack Create(int size)
{
return new StackImpl1(size);
}
}
[TestClass]
public class StackImp2Fixture : StackTest
{
protected override IStack Create(int size)
{
return new StackImpl2(size);
}
}
在每个派生的夹具中生成测试。
如果我们想要添加一个新测试,我们将它添加到StackTest
类,它会自动包含在每个派生的测试中。
如果我们添加IStack
的第三个实现,我们只需添加一个从StackTest
派生的新测试夹具并覆盖create方法。
注意:
如果被测试的类具有默认构造函数,则可以使用相同的形状,并使用Generic StackTest作为基础
public class GenStackTest<TStack> where TStack : IStack, new()
{
[TestMethod]
public void IsEmpty_NoElements()
{
var myStack = new TStack();
var exp = true;
var act = myStack.IsEmpty;
Assert.AreEqual(exp, act);
}
}
[TestClass]
public class GenStack1Fixture : GenStackTest<StackImpl1>
{
}
[TestClass]
public class GenStack2Fixture : GenStackTest<StackImpl2>
{
}