Frage

Ich Frage mich, wie zu verwenden NUnit richtig.Zuerst erstellte ich einen separaten Test-Projekt, das mit meinem Haupt-Projekt als Referenz.Aber in diesem Fall bin ich nicht in der Lage, testen Sie private Methoden.Meine Vermutung war, dass ich brauchen, um mein testcode in mein Hauptcode?!- Das scheint nicht der richtige Weg, es zu tun.(Ich mag die Idee von Versand code mit tests in es.)

Wie testen Sie private Methoden mit NUnit?

War es hilfreich?

Lösung

Im Allgemeinen richtet sich Unit-Tests eine öffentliche Schnittstelle der Klasse, auf der Theorie, dass die Umsetzung unwesentlich ist, solange die Ergebnisse aus der Client-Sicht korrekt sind.

So hat NUnit keinen Mechanismus zum Testen nicht-öffentliche Mitglieder.

Andere Tipps

Während ich, dass der Fokus der Unit-Tests zustimmen sollte die öffentliche Schnittstelle sein, erhalten Sie einen weit detailliertere Eindruck von Ihrem Code, wenn Sie auch private Methoden testen. Die MS-Test-Framework für diese durch den Einsatz von PrivateObject und Private erlaubt, tut NUnit nicht. Was ich tue, stattdessen ist:

private MethodInfo GetMethod(string methodName)
{
    if (string.IsNullOrWhiteSpace(methodName))
        Assert.Fail("methodName cannot be null or whitespace");

    var method = this.objectUnderTest.GetType()
        .GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance);

    if (method == null)
        Assert.Fail(string.Format("{0} method not found", methodName));

    return method;
}

Auf diese Weise bedeutet, dass Sie müssen nicht Verkapselung für Testbarkeit kompromittieren. Denken Sie daran, müssen Sie Ihre Binding ändern, wenn Sie private static Methoden testen möchten. Das obige Beispiel ist nur zum Beispiel Methoden.

Ein gemeinsames Muster Unit-Tests für das Schreiben ist nur öffentliche Methoden zu testen.

Wenn Sie feststellen, dass Sie viele private Methoden, die Sie testen wollen, in der Regel ist dies ein Zeichen dafür, dass Sie Ihren Code Refactoring sollte.

Es wäre falsch, diese Methoden Öffentlichkeit über die Klasse zu machen, wo sie zur Zeit leben. Das würde brechen den Vertrag, den Sie diese Klasse haben wollen.

Es kann richtig sein, sie zu einer Hilfsklasse zu bewegen und sie dort öffentlich zu machen. Diese Klasse kann nicht von Ihrem API ausgesetzt werden.

Auf diese Weise Testcode wird nie mit Ihrem öffentlichen Code gemischt.

Ein ähnliches Problem testet private Klassen, dh. Klassen, die Sie aus Ihrer Assembly nicht exportieren. In diesem Fall können Sie ausdrücklich Ihren Testcode Montag ein Freund des Produktionscode Montags machen mit dem Attribute InternalsVisibleTo.

Es ist möglich, testen Sie private Methoden durch die Erklärung Ihrer test-assembly als Freund Versammlung der Gegner der Montage testen.Siehe den link unten für details:

http://msdn.microsoft.com/en-us/library/0tke9fxk.aspx

Dies kann nützlich sein, wie es meist getrennte Ihr test-code für Ihre Produktion code.Ich haben nie verwendet diese Methode mich, wie ich noch nie gefunden, er braucht es.Ich nehme an, Sie könnten es verwenden, um zu versuchen und test extrem-test-Fälle, die kann man einfach nicht replizieren in Ihrer Testumgebung, um zu sehen, wie Ihr code verarbeitet.

Wie bereits gesagt wurde, obwohl, sollten Sie wirklich nicht brauchen, um zu testen privater Methoden.Sie mehr als likley möchten umgestalten von code in kleinere Bausteine.Ein Tipp, der helfen könnte, wenn Sie kommen umgestalten, ist es zu versuchen-und denke über die domain, die Ihr system bezieht sich auf und denken Sie über die "realen" Objekten, die Sie bewohnen diese domain.Ihre Objekte/Klassen in Ihrem system sollte direkt zu einem echten Objekt, das wird Ihnen erlauben, zu isolieren, die genaue Verhalten, die das Objekt enthalten sollte, und begrenzen auch die Objekte Verantwortung.Dies bedeutet, dass Sie die Umgestaltung logisch, anstatt nur zu machen es möglich zu testen, von einer bestimmten Methode;Sie werden in der Lage zu test die Objekte Verhalten.

Wenn Sie immer noch das Bedürfnis verspüren, test interne, dann könnten Sie auch wollen, betrachten Spott in Ihrer Prüfung, wie Sie sind likley zu wollen, um den Fokus auf ein Stück code.Spott ist, wo Sie injizieren einen die Abhängigkeiten zwischen den Objekten in es, aber die Objekte injiziert werden nicht die "echte" oder die Produktion von Objekten.Sie sind dummy-Objekte mit hardcoded Verhalten, um es leichter zu isolieren, Verhaltens-Fehlern.Rhino.Mocks ist eine beliebte gratis-mocking-framework, das im wesentlichen schreiben Sie die Objekte für Sie.TypeMock.NET (ein kommerzielles Produkt mit einer community edition verfügbar") ist ein mächtiges framework, die können die mock-CLR-Objekten.Sehr nützlich für verspotten die SqlConnection - /SqlCommand und Datatable-Klassen beispielsweise bei der Prüfung einer Datenbank-app.

Hoffentlich ist diese Antwort wird geben Sie eine bit mehr Informationen informieren Sie sich über Unit-Tests im Allgemeinen und Hilfe erhalten Sie bessere Ergebnisse von Unit-Tests.

Ich bin für die Fähigkeit, die privaten Methoden zu testen. Wenn xUnit gestartet wurde zum Testen Funktionalität bestimmt, nachdem der Code geschrieben wurde. die Schnittstelle zu testen ist für diesen Zweck ausreichend.

Unit-Tests haben zu testgetriebene Entwicklung entwickelt. mit der Fähigkeit, alle Methoden zu testen, ist nützlich für die jeweilige Anwendung.

Das Hauptziel der Unit-Tests ist es, die öffentlichen Methoden einer Klasse zu testen. Diese öffentliche Methoden werden diese privaten Methoden. Unit-Tests wird das Verhalten testen, was öffentlich zugänglich ist.

Diese Frage ist in seinen fortgeschrittenen Jahren, aber ich dachte, dass ich meinen Weg, dies zu tun teilen würde.

Im Grunde genommen habe ich alle Klassen meiner Unit-Test habe in der Baugruppe sie unter dem ‚default‘ in einem ‚Unittest‘ Namespace Prüfung ist für die Montag - jede Testdatei in einer gewickelt ist:

#if DEBUG

...test code...

#endif

Block, und all das bedeutet, dass a) es ist nicht in einer Freigabe verteilt sind und b) Ich kann internal / Friend Ebene Erklärungen ohne hoop Springen verwenden.

Die andere Sache, diese, relevanteren auf diese Frage bietet, ist die Verwendung von partial Klassen, die verwendet werden können, einen Proxy für die Prüfung private Methoden zu schaffen, so zum Beispiel so etwas wie eine private Methode zu testen, die einen ganzzahligen Wert zurückgibt :

public partial class TheClassBeingTested
{
    private int TheMethodToBeTested() { return -1; }
}

in den Hauptklassen der Versammlung, und die Testklasse:

#if DEBUG

using NUnit.Framework;

public partial class TheClassBeingTested
{
    internal int NUnit_TheMethodToBeTested()
    {
        return TheMethodToBeTested();
    }
}

[TestFixture]
public class ClassTests
{
    [Test]
    public void TestMethod()
    {
        var tc = new TheClassBeingTested();
        Assert.That(tc.NUnit_TheMethodToBeTested(), Is.EqualTo(-1));
    }
}

#endif

Natürlich müssen Sie sicherstellen, dass Sie diese Methode nicht verwenden, während der Entwicklung, wenn auch ein Releasebuild wird bald einen versehentlichen Anruf, um es anzuzeigen, wenn Sie das tun.

Entschuldigt, wenn dies nicht die Frage beantworten, sondern Lösungen, wie mithilfe von Reflektion, #if #endif Aussagen oder machen private Methoden sichtbar löst nicht das Problem. Es kann mehrere Gründe geben, nicht privaten Methoden sichtbar zu machen ... was ist, wenn es Produktionscode ist und das Team im Nachhinein ist das Schreiben von Unit-Tests zum Beispiel.

Für das Projekt, das ich arbeite nur MSTest (leider) erscheint eine Möglichkeit zu haben, Accessoren verwenden, um Unit-Test-private Methoden.

Sie nicht testen private Veranstaltungen. Es gibt Möglichkeiten, Reflexion zu verwenden, um in private Methoden und Eigenschaften zu erhalten. Aber das ist nicht wirklich einfach und ich dringend, diese Praxis entmutigen.

Sie sollten einfach nicht alles testen, die nicht öffentlich ist.

Wenn Sie einige internen Methoden und Eigenschaften haben, sollten Sie entweder zu ändern, dass die öffentlichen oder Ihre Tests versenden mit der App (etwas, das ich wirklich nicht als Problem sehen).

Wenn Ihr Kunde ist in der Lage eine Testsuite laufen und sehen, dass der Code, den Sie geliefert wird wirklich „arbeiten“, ich sehe das nicht als Problem (solange Sie Ihre IP durch das nicht weggeben ). Dinge, die ich in jedem Release enthalten sind Test-Berichte und Code-Coverage-Berichte.

Sie können Ihre Methoden geschützt interne machen und dann mit assembly: InternalVisibleTo("NAMESPACE")  zu Ihrem Testnamespace.

Daher NEIN! Sie können nicht private Methoden zugreifen, aber dies ist ein Work-around.

In der Theorie von Unit-Tests nur Vertrag geprüft werden soll. das heißt nur öffentliche Mitglieder der Klasse. Aber in der Regel in der Praxis Entwickler will interne Mitglieder testen. - und es ist nicht schlecht. Ja, es geht gegen die Theorie, aber in der Praxis kann es manchmal nützlich sein.

Also Sie, wenn wirklich interne Mitglieder wollen testen Sie eines dieser Ansätze verwenden können:

  1. Sie Ihr Mitglied der Öffentlichkeit. In vielen Bücher vorschlagen Autoren dieses Ansatz so einfach
  2. Sie können Sie Mitglieder intern machen, und fügen Sie InternalVisibleTo assebly
  3. Sie können die Teilnehmer geschützt machen und Ihre Testklasse erben von Ihrem unter Testklasse.

Codebeispiel (Pseudo-Code):

public class SomeClass
{
    protected int SomeMethod() {}
}
[TestFixture]
public class TestClass : SomeClass{

    protected void SomeMethod2() {}
    [Test]
    public void SomeMethodTest() { SomeMethod2(); }
}

Ich würde die private Methoden Paket sichtbar machen. So kann man es einigermaßen privat halten, während immer noch die Methoden testen zu können. Ich bin nicht einverstanden mit den Menschen zu sagen, dass die öffentlichen Schnittstellen die einzigen sind, die getestet werden sollen. Es ist oft sehr kritische Code in den privaten Methoden, die nicht nur richtig getestet werden können, indem sie durch die externen Schnittstellen gehen.

So ist es wirklich läuft darauf hinaus, wenn Sie kümmern sich mehr um richtige Code oder Informationen zu verbergen. Ich würde sagen, Paket Sichtbarkeit da, um einen guter Kompromiss würde diese Methode jemand den Zugriff auf ihre Klasse im Paket zu platzieren. Das soll sich wirklich zweimal darüber nachdenken, ob das ein wirklich intelligentes, was zu tun ist.

Ich bin ein Java-Typ btw, so Paket visiblilty vielleicht etwas ganz anderes in C # aufgerufen werden. Es genügt zu sagen, dass es, wenn zwei Klassen im gleichen Namensraum, um sein müssen, um diese Methoden zugreifen.

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