Semantikvorgaben via Interfaces: Code Contracts vs. Unit-Tests 
Im Posting Code Contracts für Interfaces und abstrakte Klassen habe ich beschrieben, dass Code Contracts die Möglichkeit bieten, mit einem Interface nicht nur syntaktische sondern auch semantische Vorgaben zu definieren. Eine – wenn auch nicht ganz so einfache – Alternative dazu ist das Bereitstellen von Unit-Tests für Interfaces.

Da diese das Interface nicht instanziieren können, verwenden solche Unit-Tests eine abstrakte Factory-Method, womit sie die Erstellung der konkreten Implementierung an ihre Subklassen weiterdelegieren. Das nachfolgend dargestellte Beispiel demonstriert dies. Für das Interface IStarShip wird dazu zunächst festgelegt, dass für einen negativen Übergabeparameter eine TransporterException auszulösen ist. Der abstrakte Unit-Test IStarShipTest überprüft dies. Im Zuge dessen wird die abstrakte Methode create zum erzeugen einer Instanz von StarShip verwendet. Die Implementierung dieser Methode findet sich in den Realisierung des betrachteten Interfaces. Beispielsweise erzeugt ContitutionClassStarShipTest eine Instanz von ContitutionClassStar , welche somit über diesen Unit-Test den für das Interface definierten Tests unterzogen wird.

public interface IStarShip
{
    /// <summary>
    /// Beamt die gewünschte Anzahl 
    /// an Personen an Board.
    /// Falls ein Fehler auftritt, 
    /// oder persons negativ ist, wird
    /// eine TransporterException 
    /// ausgelöst.
    /// </summary>
    /// <param name="persons">
    /// Anzahl der zu beamenden Personen
    /// </param>
    void BeamUp(int persons);
}

public abstract class IStarShipTest
{

    protected abstract IStarShip create();

    [TestMethod]
    [ExpectedException(typeof(TransporterException))]
    public void TestBeamNegativePersons()
    {
        IStarShip ship = create();
        ship.BeamUp(-1);
    }

    // Weitere Test-Methoden ...
}

public class ConstitutionClassShip : IStarShip
{
    public void BeamUp(int persons)
    {
        if (persons < 0) throw new TransporterException();
    }
}


[TestClass]
public class ContitutionClassStarShipTest: IStarShipTest
{

    protected override IStarShip create()
    {
        return new ConstitutionClassShip();
    }
}



Ralf Westphal 
Hier noch ein etwas ausführlicherer Beitrag zum Thema "semantische Kontrakte":

http://ralfw.blogspot.com/2009/02/seman ... tests.html

-Ralf

Comments 

Add Comment

Fill out the form below to add your own comments.









Insert Special:


View Uploaded Images








Moderation is turned on for this blog. Your comment will require the administrators approval before it will be visible.