How do you unit test an interface?
For example, there is a interface IMyInterface
, and three classes support this interface:
class A : IMyInterface
{
}
class B : IMyInterface
{
}
class C : IMyInterface
{
}
In the simplest way, I could write three test class : ATest, BTest, CTest and test them separately. However, since they support the same interface, most test c开发者_如何学Pythonode would be the same, it's hard to maintain. How can I use a simple and easy way to test a interface that is supported by different class?
(previously asked on the MSDN forums)
If you want to run the same tests against different implementers of your interface using NUnit as an example:
public interface IMyInterface {}
class A : IMyInterface { }
class B : IMyInterface { }
class C : IMyInterface { }
public abstract class BaseTest
{
protected abstract IMyInterface CreateInstance();
[Test]
public void Test1()
{
IMyInterface instance = CreateInstance();
//Do some testing on the instance...
}
//And some more tests.
}
[TestFixture]
public class ClassATests : BaseTest
{
protected override IMyInterface CreateInstance()
{
return new A();
}
[Test]
public void TestCaseJustForA()
{
IMyInterface instance = CreateInstance();
//Do some testing on the instance...
}
}
[TestFixture]
public class ClassBTests : BaseTest
{
protected override IMyInterface CreateInstance()
{
return new B();
}
}
[TestFixture]
public class ClassCTests : BaseTest
{
protected override IMyInterface CreateInstance()
{
return new C();
}
}
To test an interface with common tests regardless of implementation, you can use an abstract test case, and then create concrete instances of the test case for each implementation of the interface.
The abstract (base) test case performs the implementation-neutral tests (i.e. verify the interface contract) while the concrete tests take care of instantiating the object to test, and perform any implementation-specific tests.
Could create methods that take a parameter of type IMyInterface and have the actual test methods just call those methods passing in different concrete classes.
You do not test the interface directly, but you may write an abstract class that tests the contract a particular implementation should extend. A test of a concrete class would then extend the abstract class
If you're using NUnit, then you could use Grensesnitt:
public interface ICanAdd {
int Add(int i, int j); //dont ask me why you want different adders
}
public class winefoo : ICanAdd {
public int Add(int i, int j)
{
return i + j;
}
}
interface winebar : ICanAdd {
void FooBar() ;
}
public class Adder1 : winebar {
public int Add(int i, int j) {
return i + j;
}
public void FooBar() {}
}
public class Adder2 : ICanAdd {
public int Add(int i, int j) {
return (i + 12) + (j - 12 ); //yeeeeeaaaah
}
}
[InterfaceSpecification]
public class WithOtherPlugins : AppliesToAll<ICanAdd>
{
[TestCase(1, 2, 3)]
[TestCase(-1, 2, 1)]
[TestCase(0, 0, 0)]
public void CanAddOrSomething(int x, int y, int r)
{
Assert.AreEqual(subject.Add(x, y), r);
}
[TestCase(1, 2, Result = 3)]
[TestCase(-1, 2, Result = 1)]
[TestCase(0, 0, Result = 0)]
public int CannAddOrSomethingWithReturn(int x, int y) {
return subject.Add(x, y);
}
}
精彩评论