Testowanie jednostkowe metod C#

Pochodzę ze świata Java EE, ale teraz pracuję nad projektem. Net. W Javie kiedy chciaĹ 'em przetestowaÄ ‡ metodÄ ™ protected byĹ' o to Ĺ 'atwe, wystarczyĺ' o posiadanie klasy testowej o tej samej nazwie pakietu. Czy jest coś podobnego do C#? Czy istnieją jakieś dobre praktyki dotyczące jednostkowego testowania chronionych metod? Znalazłem tylko frameworki i ludzi mówiących, że powinienem testować tylko metody publiczne. Powinno być możliwe, aby to zrobić bez żadnych ram...

Wielkie dzięki.

Author: Smartboy, 2012-11-16

6 answers

Możesz odziedziczyć klasę, którą testujesz na swojej klasie testowej.

public class Test1 : SomeClass
{
    Asert.AreEqual(1, SomeClass.ProtectedMethod());
}
 55
Author: unarity,
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-07-16 10:32:54

Inną opcją jest użycie internal dla tych metod, a następnie użycie InternalsVisibleTo aby umożliwić Twojemu zespołowi testowemu dostęp do tych metod. Nie zatrzymuje to użycia metod przez inne klasy w tym samym zestawie, ale zatrzymuje dostęp do nich przez inne zestawy, które nie są twoim zestawem testowym.

To nie daje tyle hermetyzacji i ochrony, ale jest dość proste i może być przydatne.

Dodaj do AssemblyInfo.cs w zbiorze zawierającym metody wewnętrzne

[assembly: InternalsVisibleTo("TestsAssembly")]
 11
Author: Richard Garside,
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-09-12 09:14:42

Możesz ujawnić chronione metody w nowej klasie, która dziedziczy klasę, którą chcesz przetestować.

public class ExposedClassToTest : ClassToTest
{
    public bool ExposedProtectedMethod(int parameter)
    {
        return base.ProtectedMethod(parameter);
    }
}
 6
Author: typhon04,
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-07-16 08:19:39

Możesz użyć reflection do wywołania prywatnych i chronionych metod.

Zobacz tutaj po więcej:

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

 3
Author: Justin Harvey,
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-11-16 12:10:15

Możesz użyć klasy PrivateObject, aby uzyskać dostęp do wszystkich prywatnych/ chronionych metod/ pól.

PrivateObject jest klasą w ramach Microsoft unit testing Framework, która jest opakowaniem umożliwiającym wywołanie normalnie niedostępnych członków do testów jednostkowych.

 3
Author: Usama Aslam,
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
2018-02-14 13:04:17

Chociaż zaakceptowana odpowiedź jest najlepsza, nie rozwiązała mojego problemu. / Align = "center" bgcolor = "# e0ffe0 " / cesarz chin / / align = center / W końcu zdecydowałem się wyodrębnić logikę do przetestowania do publicznej klasy i przetestować to. Na pewno nie będzie to działać dla wszystkich i może wymagać sporo refaktoryzacji, ale jeśli przewiń całą drogę do tej odpowiedzi, może to po prostu pomóc. :) Oto przykład

Stare situation:

protected class ProtectedClass{
   protected void ProtectedMethod(){
      //logic you wanted to test but can't :(
   }
}

Nowa sytuacja:

protected class ProtectedClass{
   private INewPublicClass _newPublicClass;

   public ProtectedClass(INewPublicClass newPublicClass) {
      _newPublicClass = newPublicClass;
   }

   protected void ProtectedMethod(){
      //the logic you wanted to test has been moved to another class
      _newPublicClass.DoStuff();
   }
}

public class NewPublicClass : INewPublicClass
{
   public void DoStuff() {
      //this logic can be tested!
   }
}

public class NewPublicClassTest
{
    NewPublicClass _target;
    public void DoStuff_WithoutInput_ShouldSucceed() {
        //Arrange test and call the method with the logic you want to test
        _target.DoStuff();
    }
}
 0
Author: nozem,
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
2018-09-17 12:48:31