Frage

Ich habe einige Klassen mit ähnlichem Verhalten entwickelt, die alle die gleiche Schnittstelle implementieren.Ich habe eine Factory implementiert, die das entsprechende Objekt erstellt und die Schnittstelle zurückgibt.Ich schreibe einen Unit-Test für die Fabrik.Alles, was Sie zurückerhalten, ist eine Schnittstelle zum Objekt.Wie kann man am besten testen, ob die Fabrik ordnungsgemäß funktioniert hat?

Ich würde gerne die Antwort in Java wissen, aber wenn es eine sprachübergreifende Lösung gibt, würde ich sie gerne wissen.

Nummer 2.würde in der Antwort wie in der anderen Antwort vorgegangen werden?Wenn ja, werde ich auch die andere Antwort als akzeptiert markieren und meine Frage umformulieren, um sowohl eine Factory zu adressieren, in der eine Schnittstelle zurückgegeben wird und Sie keine Ahnung haben, welche Art von konkreter Klasse die Schnittstelle implementiert hat, als auch den Fall, in dem Sie wissen, um welche konkrete Klasse es sich handelt gebraucht.

War es hilfreich?

Lösung

Da ich nicht weiß, wie Ihre Factory-Methode aussieht, kann ich Ihnen im Moment nur dazu raten

  1. Überprüfen Sie, ob das Objekt die richtige konkrete Implementierung ist, nach der Sie gesucht haben:

    IMyInterface fromFactory = factory.create(...);  
    Assert.assertTrue(fromFactory instanceof MyInterfaceImpl1);
    
  2. Sie können überprüfen, ob die konkreten Instanzen werkseitig mit gültigen Instanzvariablen eingerichtet wurden.

Andere Tipps

Was Sie versuchen, ist kein Unit-Test

Wenn Sie testen, ob die zurückgegebenen Objekte Instanzen bestimmter konkreter Klassen sind, handelt es sich nicht um einen Komponententest.Sie führen Integrationstests durch.Obwohl Integrationstests wichtig sind, sind sie nicht dasselbe.

Beim Unit-Test müssen Sie nur das Objekt selbst testen.Wenn Sie den konkreten Typ der zurückgegebenen abstrakten Objekte bestätigen, testen Sie die Implementierung des zurückgegebenen Objekts.

Unit-Tests für Objekte im Allgemeinen

Beim Unit-Testen gibt es vier Dinge, die Sie bestätigen möchten:

  1. Die Rückgabewerte von Abfragen (nicht void-Methoden) entsprechen Ihren Erwartungen.
  2. Nebenwirkungen von Befehlen (void-Methoden) verändern das Objekt selbst wie erwartet.
  3. An andere Objekte gesendete Befehle werden empfangen (dies geschieht normalerweise mithilfe von Mocks).

Darüber hinaus möchten Sie nur testen, was an einer Objektinstanz beobachtet werden konnte, d. h.die öffentliche Schnittstelle.Andernfalls binden Sie sich an bestimmte Implementierungsdetails.Dies würde erfordern, dass Sie Ihre Tests ändern, wenn sich diese Details ändern.

Unit-Test-Fabriken

Unit-Tests auf Fabriken sind wirklich uninteressant, weil Sie sind nicht am Verhalten der zurückgegebenen Objekte von Abfragen interessiert.Dieses Verhalten wird (hoffentlich) an anderer Stelle getestet, vermutlich beim Unit-Testen dieses Objekts selbst.Sie sind nur wirklich daran interessiert, ob das zurückgegebene Objekt das Richtige hat oder nicht Typ, was garantiert ist, wenn Ihr Programm kompiliert wird.

Da sich Fabriken im Laufe der Zeit nicht ändern (weil sie dann „Bauwerke“ wären, was ein anderes Muster ist), gibt es keine Befehle zum Testen.

Fabriken sind für die Instanziierung von Objekten verantwortlich und sollten daher nicht darauf angewiesen sein, dass andere Fabriken dies für sie tun.Sie könnte hängen von einem Builder ab, aber trotzdem sollen wir nicht die Richtigkeit des Builders testen, sondern nur, ob der Builder die Nachricht empfängt oder nicht.

Das bedeutet, dass Sie bei Factories lediglich testen müssen, ob sie die Nachrichten an die Objekte senden, von denen sie abhängen.Wenn Sie Dependency Injection verwenden, ist dies nahezu trivial.Verspotten Sie einfach die Abhängigkeiten in Ihren Komponententests und überprüfen Sie, ob sie die Nachrichten empfangen.

Zusammenfassung der Unit-Testing-Fabriken

  1. Testen Sie weder das Verhalten noch die Implementierungsdetails der zurückgegebenen Objekte!Ihre Factory ist nicht für die Implementierung der Objektinstanzen verantwortlich!
  2. Testen Sie, ob die an Abhängigkeiten gesendeten Befehle empfangen werden.

Das ist es.Wenn keine Abhängigkeiten vorhanden sind, gibt es nichts zu testen.Außer vielleicht, um zu behaupten, dass das zurückgegebene Objekt kein ist null Referenz.

Integrationstestfabriken

Wenn Sie eine Anforderung haben, dass der zurückgegebene abstrakte Objekttyp eine Instanz eines bestimmten konkreten Typs ist, dann fällt dies unter den Integrationstest.

Andere hier haben bereits geantwortet, wie man das mit dem macht instanceof Operator.

@cem-catikkas Ich denke, es wäre korrekter, die Werte von getClass().getName() zu vergleichen.Falls die Klasse „MyInterfaceImpl1“ eine Unterklasse ist, könnte Ihr Test fehlerhaft sein, da die Unterklasse eine Instanz von „MyInterfaceImpl1“ ist.Ich würde es wie folgt umschreiben:

IMyInterface fromFactory = factory.create(...);  
Assert.assertEquals(fromFactory.getClass().getName(), MyInterfaceImpl1.class.getName());

Wenn Sie glauben, dass dies auf irgendeine Weise fehlschlagen könnte (das kann ich mir nicht vorstellen), führen Sie die beiden Überprüfungen durch.

if (myNewObject instanceof CorrectClass)
{
    /* pass test */
}

aktualisieren:

Ich weiß nicht, warum dies herabgesetzt wurde, deshalb werde ich es etwas erweitern ...

public void doTest()
{
    MyInterface inst = MyFactory.createAppropriateObject();
    if (! inst instanceof ExpectedConcreteClass)
    {
        /* FAIL */
    }
}

Wenn Ihre Factory eine konkrete Instanz zurückgibt, können Sie diese verwenden @Parameter Annotation, um einen flexibleren automatischen Unit-Test zu erhalten.

package it.sorintlab.pxrm.proposition.model.factory.task;

import org.junit.Test;

import java.util.Arrays;
import java.util.Collection;

import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

import static org.junit.Assert.*;

@RunWith(Parameterized.class)
public class TaskFactoryTest {

    @Parameters
    public static Collection<Object[]> data() {
        return Arrays.asList(new Object[][] {
                { "sas:wp|repe" , WorkPackageAvailabilityFactory.class},
                { "sas:wp|people", WorkPackagePeopleFactory.class},
                { "edu:wp|course", WorkPackageCourseFactory.class},
                { "edu:wp|module", WorkPackageModuleFactory.class},
                { "else", AttachmentTaskDetailFactory.class}
        });
    }

    private String fInput;
    private Class<? extends TaskFactory> fExpected;

    public TaskFactoryTest(String input, Class<? extends TaskFactory> expected) {
        this.fInput = input;
        this.fExpected = expected;
    }

    @Test
    public void getFactory() {
        assertEquals(fExpected, TaskFactory.getFactory(fInput).getClass());
    }
}

Dieses Beispiel wurde mit erstellt Junit4.Sie werden feststellen, dass Sie mit nur einer Codezeile das gesamte Ergebnis Ihrer Factory-Methode testen können.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top