Как вы тестируете интерфейс? - PullRequest
23 голосов
/ 26 июня 2010

Например, есть интерфейс IMyInterface, и три класса поддерживают этот интерфейс:

class A : IMyInterface
{
}

class B : IMyInterface
{
}

class C : IMyInterface
{
}

Проще всего, я мог бы написать три тестовых класса: ATest, BTest, CTest и протестировать их отдельно. Однако, поскольку они поддерживают один и тот же интерфейс, большинство тестового кода будет одинаковым, его сложно поддерживать. Как я могу использовать простой и легкий способ тестирования интерфейса, поддерживаемого другим классом?

( ранее задавался на форумах MSDN )

Ответы [ 5 ]

41 голосов
/ 26 июня 2010

Если вы хотите запускать одинаковые тесты для разных исполнителей вашего интерфейса, используя NUnit в качестве примера:

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();
    }
}
19 голосов
/ 26 июня 2010

Чтобы протестировать интерфейс с общими тестами независимо от реализации, вы можете использовать абстрактный тестовый пример, а затем создать конкретные экземпляры тестового примера для каждой реализации интерфейса.

Абстрактный (базовый) тестcase выполняет независимые от реализации тесты (т. е. проверяют контракт интерфейса), в то время как конкретные тесты заботятся о создании объекта для тестирования и выполняют любые специфичные для реализации тесты.

3 голосов
/ 26 июня 2010

Может создавать методы, которые принимают параметр типа IMyInterface и имеют фактические методы тестирования, просто вызывая эти методы, передавая разные конкретные классы.

2 голосов
/ 26 июня 2010

Вы не тестируете интерфейс напрямую, но вы можете написать абстрактный класс, который тестирует контракт, который должна расширять конкретная реализация. Тест конкретного класса расширил бы абстрактный класс

0 голосов
/ 24 сентября 2015

Если вы используете NUnit, вы можете использовать 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);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...