Подтвердить что ты не робот

Как вы unit test интерфейс?

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

class A : IMyInterface
{
}

class B : IMyInterface
{
}

class C : IMyInterface
{
}

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

(ранее заданный на форумах MSDN)

4b9b3361

Ответ 1

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

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

Ответ 2

Если вы хотите использовать те же тесты для разных исполнителей вашего интерфейса, используя 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();
    }
}

Ответ 3

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

Ответ 4

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

Ответ 5

Если вы используете 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);
    }
}