Jak testować metody prywatne?

Buduję bibliotekę klas, która będzie miała kilka publicznych i prywatnych metod. Chcę mieć możliwość jednostkowego testowania prywatnych metod (głównie podczas opracowywania, ale może być również przydatna do przyszłej refaktoryzacji).

Jak to zrobić?

Author: Eric Labashosky, 2008-10-30

30 answers

Jeśli używasz. NET, powinieneś użyć InternalsVisibleToAttribute .

 113
Author: TcKs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-14 10:14:44

Jeśli chcesz przetestować metodę prywatną, coś może być nie tak. Testy jednostkowe są (ogólnie rzecz biorąc) przeznaczone do testowania interfejsu klasy, czyli jej publicznych (i chronionych) metod. Możesz oczywiście "zhakować" rozwiązanie tego problemu (nawet jeśli tylko upubliczniasz metody), ale możesz również rozważyć:

  1. Jeśli metoda, którą chcesz przetestować, jest naprawdę warta przetestowania, może warto przenieść ją do własnej klasy.
  2. Dodaj więcej testów do publicznych metod, które wywołują metoda prywatna, testowanie funkcjonalności metody prywatnej. (Jak wskazali komentatorzy, powinieneś to zrobić tylko wtedy, gdy funkcjonalność tych prywatnych metod jest naprawdę częścią publicznego interfejsu. Jeśli faktycznie wykonują funkcje, które są ukryte przed użytkownikiem (np. test jednostkowy), jest to prawdopodobnie złe).
 334
Author: Jeroen Heijmans,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-31 07:38:18

Testowanie prywatnych metod może nie być przydatne. Jednak czasami lubię też wywoływać metody prywatne z metod testowych. Przez większość czasu, aby zapobiec powielaniu kodu do generowania danych testowych...

Microsoft udostępnia do tego dwa mechanizmy:

Accessors

  • Goto kodu źródłowego definicji klasy
  • Kliknij prawym przyciskiem myszy nazwę klasy
  • Wybierz "Utwórz Prywatny Dostęp"
  • Wybierz projekt, w którym accessor powinien zostać utworzony => Otrzymasz nową klasę o nazwie foo_accessor. Klasa ta będzie dynamicznie generowana podczas kompilacji i będzie publicznie dostępna dla wszystkich członków.

Jednakże, mechanizm jest czasami trochę trudny do rozwiązania, jeśli chodzi o zmiany interfejsu oryginalnej klasy. Więc większość razy unikam tego.

Klasa PrivateObject Innym sposobem jest użycie Microsoft.VisualStudio.TestTools./ Align = "left" / PrivateObject

// Wrap an already existing instance
PrivateObject accessor = new PrivateObject( objectInstanceToBeWrapped );

// Retrieve a private field
MyReturnType accessiblePrivateField = (MyReturnType) accessor.GetField( "privateFieldName" );

// Call a private method
accessor.Invoke( "PrivateMethodName", new Object[] {/* ... */} );
 113
Author: Seven,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-10 10:57:32

Nie zgadzam się z filozofią "powinieneś być zainteresowany tylko testowaniem interfejsu zewnętrznego". To trochę jak stwierdzenie, że warsztat samochodowy powinien mieć tylko testy, aby sprawdzić, czy koła się obracają. Tak, ostatecznie interesuje mnie zachowanie zewnętrzne, ale lubię, aby moje własne, prywatne, wewnętrzne testy były nieco bardziej szczegółowe i do rzeczy. Tak, jeśli refaktor, może będę musiał zmienić niektóre testy, ale jeśli nie jest to ogromny refaktor, będę musiał zmienić tylko kilka i fakt, że inne (niezmienione) testy wewnętrzne nadal działają, jest świetnym wskaźnikiem, że refaktoryzacja zakończyła się sukcesem.

Możesz spróbować pokryć wszystkie wewnętrzne przypadki używając tylko publicznego interfejsu i teoretycznie możliwe jest przetestowanie każdej wewnętrznej metody (lub przynajmniej każdej, która ma znaczenie) całkowicie za pomocą publicznego interfejsu, ale być może będziesz musiał skończyć stojąc na głowie, aby to osiągnąć i połączenie między przypadkami testowymi uruchamianymi przez publiczny interfejs i wewnętrzną część. rozwiązanie, które mają przetestować, może być trudne lub niemożliwe do wykrycia. Po zaznaczeniu, indywidualne testy, które gwarantują, że wewnętrzna maszyna działa prawidłowo, są warte drobnych zmian testowych, które następują po refaktoryzacji - przynajmniej to było moje doświadczenie. Jeśli musisz dokonać ogromnych zmian w testach dla każdego refaktoryzacji, to może to nie ma sensu, ale w takim przypadku może powinieneś całkowicie przemyśleć swój projekt. Dobry projekt powinien być elastyczny wystarczająco, aby umożliwić większość zmian bez masowych przeprojektowań.

 75
Author: Darrell Plank,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-19 06:34:08

W rzadkich przypadkach chciałem przetestować funkcje prywatne, Zwykle modyfikowałem je tak, aby były chronione, a ja napisałem podklasę z publiczną funkcją wrappera.

Klasa:

...

protected void APrivateFunction()
{
    ...
}

...

Podklasa do testów:

...

[Test]
public void TestAPrivateFunction()
{
    APrivateFunction();
    //or whatever testing code you want here
}

...
 50
Author: Jason Jackson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-30 16:04:04

Myślę, że bardziej fundamentalne pytanie powinno zostać zadane, dlaczego próbujesz przetestować metodę prywatną w pierwszej kolejności. Jest to zapach kodu, który próbujesz przetestować prywatną metodę poprzez publiczny interfejs tej klasy, podczas gdy ta metoda jest prywatna z jakiegoś powodu, ponieważ jest to szczegół implementacji. Należy się jedynie troszczyć o zachowanie interfejsu publicznego, a nie o to, jak jest on wdrażany pod przykrywką.

Jeśli chcę sprawdzić zachowanie prywatnego metoda, używając common refactorings, mogę wyodrębnić jego kod do innej klasy(może z widocznością na poziomie pakietu, więc upewnij się, że nie jest częścią publicznego API). Następnie mogę przetestować jego zachowanie w izolacji.

Iloczyn refaktoryzacji oznacza, że metoda prywatna jest teraz osobną klasą, która stała się współpracownikiem klasy oryginalnej. Jego zachowanie zostanie dobrze zrozumiane dzięki własnym testom jednostkowym.

Mogę wtedy wyśmiewać jego zachowanie, gdy próbuję przetestować oryginał Klasa, aby móc skoncentrować się na testowaniu zachowania publicznego interfejsu tej klasy, a nie na testowaniu kombinatorycznej eksplozji publicznego interfejsu i zachowania wszystkich jego prywatnych metod.

Widzę to analogicznie do jazdy samochodem. Kiedy prowadzę samochód, nie jeżdżę z maską w górze, więc widzę, że silnik działa. Polegam na interfejsie, który zapewnia samochód, a mianowicie liczniku obrotów i prędkościomierzu, aby wiedzieć, że silnik działa. Polegam na tym, że samochód faktycznie porusza się, gdy naciskam pedał gazu. Jeśli chcę przetestować silnik, mogę to sprawdzić w izolacji. : D

Oczywiście testowanie prywatnych metod bezpośrednio może być ostatecznością, jeśli masz starszą aplikację, ale wolałbym, aby starszy kod został zrefaktorowany, aby umożliwić lepsze testowanie. Michael Feathers napisał świetną książkę na ten temat. http://www.amazon.co.uk/Working-Effectively-Legacy-Robert-Martin/dp/0131177052

 21
Author: Big Kahuna,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-24 16:30:01

Typy prywatne, wewnętrzne i prywatne członkowie są tak z jakiegoś powodu i często nie chcesz z nimi zadzierać bezpośrednio. A jeśli to zrobisz, są szanse, że złamiesz później, ponieważ nie ma gwarancji, że faceci, którzy stworzyli te zespoły, zachowają prywatne / wewnętrzne implementacje jako takie.

Ale czasami, gdy robię jakieś hacki / eksplorację skompilowanych lub zewnętrznych zestawów, ja sam skończyłem chcąc zainicjować prywatną klasę lub klasę z konstruktor prywatny lub wewnętrzny. Czasami, gdy mam do czynienia z wstępnie skompilowanymi starszymi bibliotekami, których nie mogę zmienić-kończę pisanie testów na prywatnej metodzie.

Tak narodził się AccessPrivateWrapper - http://amazedsaint.blogspot.com/2010/05/accessprivatewrapper-c-40-dynamic.html - jest to klasa szybkiego wrappera, która ułatwi pracę za pomocą dynamicznych funkcji C# 4.0 i reflection.

Możesz tworzyć wewnętrzne / prywatne typy jak

    //Note that the wrapper is dynamic
    dynamic wrapper = AccessPrivateWrapper.FromType
        (typeof(SomeKnownClass).Assembly,"ClassWithPrivateConstructor");

    //Access the private members
    wrapper.PrivateMethodInPrivateClass();
 17
Author: amazedsaint,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-25 07:44:15

Użyłem również metody InternalsVisibleToAttribute. Warto również wspomnieć, że jeśli czujesz się nieswojo, czyniąc Swoje wcześniej prywatne metody wewnętrznymi, aby to osiągnąć, to może i tak nie powinny być przedmiotem bezpośrednich testów jednostkowych.

W końcu testujesz zachowanie swojej klasy, a nie konkretną implementację - możesz zmienić to drugie, nie zmieniając tego pierwszego, a testy i tak powinny przejść.

 10
Author: philsquared,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-30 15:55:36

Możesz przetestować prywatną metodę na dwa sposoby.]}

  1. Możesz utworzyć instancję klasy PrivateObject składnia jest następująca

    PrivateObject obj= new PrivateObject(PrivateClass);
    //now with this obj you can call the private method of PrivateCalss.
    obj.PrivateMethod("Parameters");
    
  2. Możesz użyć refleksji.
    PrivateClass obj = new PrivateClass(); // Class containing private obj
    Type t = typeof(PrivateClass); 
    var x = t.InvokeMember("PrivateFunc", 
        BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Public |  
            BindingFlags.Instance, null, obj, new object[] { 5 });
    
 10
Author: Unknown,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-27 12:08:43

MS Test ma wbudowaną funkcję, która sprawia, że prywatne elementy i metody są dostępne w projekcie, tworząc plik o nazwie VSCodeGenAccessors

[System.Diagnostics.DebuggerStepThrough()]
    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TestTools.UnitTestGeneration", "1.0.0.0")]
    internal class BaseAccessor
    {

        protected Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject m_privateObject;

        protected BaseAccessor(object target, Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType type)
        {
            m_privateObject = new Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject(target, type);
        }

        protected BaseAccessor(Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType type)
            :
                this(null, type)
        {
        }

        internal virtual object Target
        {
            get
            {
                return m_privateObject.Target;
            }
        }

        public override string ToString()
        {
            return this.Target.ToString();
        }

        public override bool Equals(object obj)
        {
            if (typeof(BaseAccessor).IsInstanceOfType(obj))
            {
                obj = ((BaseAccessor)(obj)).Target;
            }
            return this.Target.Equals(obj);
        }

        public override int GetHashCode()
        {
            return this.Target.GetHashCode();
        }
    }

Z klasami, które pochodzą z BaseAccessor

Takie jak

[System.Diagnostics.DebuggerStepThrough()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TestTools.UnitTestGeneration", "1.0.0.0")]
internal class SomeClassAccessor : BaseAccessor
{

    protected static Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType m_privateType = new Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType(typeof(global::Namespace.SomeClass));

    internal SomeClassAccessor(global::Namespace.Someclass target)
        : base(target, m_privateType)
    {
    }

    internal static string STATIC_STRING
    {
        get
        {
            string ret = ((string)(m_privateType.GetStaticField("STATIC_STRING")));
            return ret;
        }
        set
        {
            m_privateType.SetStaticField("STATIC_STRING", value);
        }
    }

    internal int memberVar    {
        get
        {
            int ret = ((int)(m_privateObject.GetField("memberVar")));
            return ret;
        }
        set
        {
            m_privateObject.SetField("memberVar", value);
        }
    }

    internal int PrivateMethodName(int paramName)
    {
        object[] args = new object[] {
            paramName};
        int ret = (int)(m_privateObject.Invoke("PrivateMethodName", new System.Type[] {
                typeof(int)}, args)));
        return ret;
    }
 8
Author: Marcus King,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-30 16:10:23

Istnieją 2 rodzaje metod prywatnych. Statyczne metody prywatne i Niestatyczne metody prywatne (metody instancji). Poniższe 2 Artykuły wyjaśniają, jak testować metody prywatne za pomocą przykładów.

  1. Testowanie Jednostkowe Statycznych Metod Prywatnych
  2. Testowanie Jednostkowe Niestatyczne Metody Prywatne
 8
Author: Venkat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-06 05:39:26

Zazwyczaj nie używam dyrektyw kompilatora, ponieważ szybko wszystko zaśmiecają. Jednym ze sposobów na złagodzenie tego, jeśli naprawdę ich potrzebujesz, jest umieszczenie ich w częściowej klasie i zignorowanie tego.plik cs podczas tworzenia wersji produkcyjnej.

 5
Author: swilliams,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-30 15:59:57

Na CodeProject znajduje się artykuł, który pokrótce omawia zalety i wady testowania prywatnych metod. Następnie dostarcza jakiś kod odbicia, aby uzyskać dostęp do prywatnych metod (podobnie jak kod podany powyżej.) Jedyny problem jaki znalazłem z próbką to to, że kod nie uwzględnia przeciążonych metod.

Artykuł znajdziesz tutaj:

Http://www.codeproject.com/KB/cs/testnonpublicmembers.aspx

 5
Author: Pedro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-04 18:35:05

Zadeklaruj je internal, a następnie użyj InternalsVisibleToAttribute aby twój zespół testów jednostkowych mógł je zobaczyć.

 4
Author: James Curran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-30 15:56:18

Czasami dobrze jest przetestować prywatne deklaracje. Zasadniczo, kompilator ma tylko jedną publiczną metodę: Compile (string outputFileName, params string[] sourceSFileNames ). Jestem pewien, że rozumiesz, że trudno byłoby przetestować taką metodę bez testowania każdej "ukrytej" deklaracji!

Dlatego stworzyliśmy Visual T# : aby ułatwić testy. Jest to darmowy język programowania. NET (kompatybilny z C# v2.0).

Dodaliśmy '.- centrala. Zachowuj się jak".' operator, poza tym możesz również uzyskać dostęp do dowolnej ukrytej deklaracji z testów bez zmiany czegokolwiek w testowanym projekcie.

Zajrzyj na naszą Stronę: Pobierz it za darmo.

 3
Author: Ludovic Dubois,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-01 17:24:05

W ogóle nie powinieneś testować prywatnych metod Twojego kodu. Powinieneś testować 'publiczny interfejs' lub API, publiczne rzeczy Twoich klas. API to wszystkie publiczne metody, które wystawiasz zewnętrznym wywoływaczom.

Powodem jest to, że gdy zaczniesz testować prywatne metody i wewnętrzne elementy Twojej klasy, połączysz implementację swojej klasy (prywatnych rzeczy) z testami. Oznacza to, że gdy zdecydujesz się na zmianę szczegółów wdrożenia będziesz również musiał zmienić swoje testy.

Z tego powodu należy unikać stosowania wewnętrznego leku.

Oto świetna rozmowa Iana Coopera, która obejmuje ten temat: Ian Cooper: TDD, where did it all go wrong

 3
Author: cda01,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-03 00:49:27

MbUnit ma ładną okładkę do tego o nazwie Reflector.

Reflector dogReflector = new Reflector(new Dog());
dogReflector.Invoke("DreamAbout", DogDream.Food);

Można również ustawić i pobrać wartości z właściwości

dogReflector.GetProperty("Age");
Jeśli chodzi o "test prywatny" to się z tym Zgadzam.. w idealnym świecie. nie ma sensu robić prywatnych testów jednostkowych. Ale w prawdziwym świecie może skończyć się chęć pisania prywatnych testów zamiast refaktoryzacji kodu.
 2
Author: Carl Bergquist,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-24 07:12:54

Jestem zaskoczony, że nikt jeszcze tego nie powiedział, Ale rozwiązaniem, które zastosowałem, jest stworzenie statycznej metody wewnątrz klasy, aby sprawdzić się. Daje to dostęp do wszystkiego, co publiczne i prywatne, aby przetestować.

Ponadto, w języku skryptowym (ze zdolnościami OO, takimi jak Python, Ruby i PHP), możesz sprawdzić sam plik po uruchomieniu. Fajny szybki sposób na upewnienie się, że Twoje zmiany niczego nie zepsują. To oczywiście sprawia, że skalowalne rozwiązanie do testowania wszystkich klas: po prostu uruchom wszystkie. (możesz to zrobić również w innych językach z void main, który zawsze uruchamia swoje testy).

 2
Author: rube,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-06 09:24:59

Chcę stworzyć przejrzysty przykład kodu, który możesz użyć na dowolnej klasie, w której chcesz przetestować prywatną metodę.

W klasie przypadków testowych po prostu dołącz te metody, a następnie zastosuj je zgodnie ze wskazówkami.

  /**
   *
   * @var Class_name_of_class_you_want_to_test_private_methods_in
   * note: the actual class and the private variable to store the 
   * class instance in, should at least be different case so that
   * they do not get confused in the code.  Here the class name is
   * is upper case while the private instance variable is all lower
   * case
   */
  private $class_name_of_class_you_want_to_test_private_methods_in;

  /**
   * This uses reflection to be able to get private methods to test
   * @param $methodName
   * @return ReflectionMethod
   */
  protected static function getMethod($methodName) {
    $class = new ReflectionClass('Class_name_of_class_you_want_to_test_private_methods_in');
    $method = $class->getMethod($methodName);
    $method->setAccessible(true);
    return $method;
  }

  /**
   * Uses reflection class to call private methods and get return values.
   * @param $methodName
   * @param array $params
   * @return mixed
   *
   * usage:     $this->_callMethod('_someFunctionName', array(param1,param2,param3));
   *  {params are in
   *   order in which they appear in the function declaration}
   */
  protected function _callMethod($methodName, $params=array()) {
    $method = self::getMethod($methodName);
    return $method->invokeArgs($this->class_name_of_class_you_want_to_test_private_methods_in, $params);
  }

$this - > _callmethod ('_someFunctionName', array (param1,param2,param3));

Po prostu podaj parametry w kolejności, w jakiej pojawiają się w oryginalnej funkcji prywatnej

 2
Author: Damon Hogan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-16 23:01:29

Dla każdego, kto chce uruchomić prywatne metody bez tych wszystkich fess i bałaganu. Działa to z każdym frameworkiem do testowania jednostkowego, używającym tylko starej, dobrej refleksji.

public class ReflectionTools
{
    // If the class is non-static
    public static Object InvokePrivate(Object objectUnderTest, string method, params object[] args)
    {
        Type t = objectUnderTest.GetType();
        return t.InvokeMember(method,
            BindingFlags.InvokeMethod |
            BindingFlags.NonPublic |
            BindingFlags.Instance |
            BindingFlags.Static,
            null,
            objectUnderTest,
            args);
    }
    // if the class is static
    public static Object InvokePrivate(Type typeOfObjectUnderTest, string method, params object[] args)
    {
        MemberInfo[] members = typeOfObjectUnderTest.GetMembers(BindingFlags.NonPublic | BindingFlags.Static);
        foreach(var member in members)
        {
            if (member.Name == method)
            {
                return typeOfObjectUnderTest.InvokeMember(method, BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.InvokeMethod, null, typeOfObjectUnderTest, args);
            }
        }
        return null;
    }
}

Następnie w Twoich rzeczywistych testach możesz zrobić coś takiego:

Assert.AreEqual( 
  ReflectionTools.InvokePrivate(
    typeof(StaticClassOfMethod), 
    "PrivateMethod"), 
  "Expected Result");

Assert.AreEqual( 
  ReflectionTools.InvokePrivate(
    new ClassOfMethod(), 
    "PrivateMethod"), 
  "Expected Result");
 2
Author: Erick Stone,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-16 18:32:30
CC -Dprivate=public
 1
Author: Mark Harrison,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-31 07:44:44
 1
Author: Ruben Bartelink,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-12 20:54:55

Oto dobry Artykuł o testowaniu jednostkowym metod prywatnych. Ale nie jestem pewien, co jest lepsze, aby zrobić aplikację zaprojektowaną specjalnie do testowania (to jak tworzenie testów tylko do testowania) lub użyć reflexion do testowania. Większość z nas wybierze drugą drogę.

 1
Author: Johnny_D,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-11 15:14:21

Używam klasy PrivateObject . Ale jak wspomniano wcześniej lepiej unikać testowania prywatnych metod.

Class target = new Class();
PrivateObject obj = new PrivateObject(target);
var retVal = obj.Invoke("PrivateMethod");
Assert.AreEqual(retVal);
 1
Author: vsapiha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-21 11:57:22

Możesz wygenerować metodę testową dla prywatnej metody z Visual studio 2008. Podczas tworzenia testu jednostkowego dla metody prywatnej do projektu testowego dodawany jest folder referencji testowych, a do tego folderu dodawany jest accessor. Akcesor jest również określany w logice metody badania jednostkowego. Ten accessor pozwala testowi jednostkowemu wywoływać metody prywatne w kodzie, który testujesz. Po szczegóły zajrzyj at

Http://msdn.microsoft.com/en-us/library/bb385974.aspx

 0
Author: Sarath,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-28 20:48:15

Zauważ również, że InternalsVisibleToAtrribute ma wymóg, aby twój zespół był mocny o nazwie, co tworzy własny zestaw problemów, jeśli pracujesz w rozwiązaniu, które wcześniej nie miało tego wymogu. Używam accessora do testowania prywatnych metod. Zobacz to pytanie że na przykład tego.

 0
Author: Chuck Dee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:15

Oto przykład, najpierw podpis metody:

private string[] SplitInternal()
{
    return Regex.Matches(Format, @"([^/\[\]]|\[[^]]*\])+")
                        .Cast<Match>()
                        .Select(m => m.Value)
                        .Where(s => !string.IsNullOrEmpty(s))
                        .ToArray();
}

Oto test:

/// <summary>
///A test for SplitInternal
///</summary>
[TestMethod()]
[DeploymentItem("Git XmlLib vs2008.dll")]
public void SplitInternalTest()
{
    string path = "pair[path/to/@Key={0}]/Items/Item[Name={1}]/Date";
    object[] values = new object[] { 2, "Martin" };
    XPathString xp = new XPathString(path, values);

    PrivateObject param0 = new PrivateObject(xp);
    XPathString_Accessor target = new XPathString_Accessor(param0);
    string[] expected = new string[] {
        "pair[path/to/@Key={0}]",
        "Items",
        "Item[Name={1}]",
        "Date"
    };
    string[] actual;
    actual = target.SplitInternal();
    CollectionAssert.AreEqual(expected, actual);
}
 0
Author: Chuck Savage,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-17 18:05:35

Sposobem na to jest posiadanie swojej metody protected i napisanie testu, który dziedziczy Twoją klasę do przetestowania. W ten sposób nie zmieniasz swojej metody public, ale włączasz testowanie.

 0
Author: octoback,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-22 18:34:04

1) Jeśli masz kod legacy, to jedynym sposobem na przetestowanie prywatnych metod jest refleksja.

2) jeśli jest to nowy kod, masz następujące opcje:

  • Użyj reflection (to complicated)
  • napisać test jednostkowy w tej samej klasie (sprawia, że kod produkcyjny jest brzydki przez posiadanie kodu testowego również w nim)
  • Refaktor i upublicznienie metody w jakiejś klasie util
  • Użyj adnotacji @ VisibleForTesting i Usuń Prywatne

Wolę adnotację metoda, najprostsza i najmniej skomplikowana. Jedynym problemem jest to, że zwiększyliśmy widoczność, co moim zdaniem nie jest wielkim problemem. Zawsze powinniśmy kodować do interfejsu, więc jeśli mamy interfejs MyService i implementację MyServiceImpl, to możemy mieć odpowiednie klasy testowe, które są MyServiceTest (metody interfejsu testowego) i MyServiceImplTest (prywatne metody testowe). Wszyscy klienci i tak powinni używać interfejsu tak w pewien sposób, nawet jeśli widoczność prywatnej metody został zwiększony to nie powinno mieć znaczenia.

 0
Author: anuj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-18 15:40:29

Możesz również zadeklarować go jako publiczny lub wewnętrzny (z InternalsVisibleToAttribute) podczas budowania w trybie debugowania:

    /// <summary>
    /// This Method is private.
    /// </summary>
#if DEBUG
    public
#else
    private
#endif
    static string MyPrivateMethod()
    {
        return "false";
    }

Wydmuchuje kod, ale będzie to private w kompilacji release.

 0
Author: Alex H,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-27 14:44:00