Підрозділи класів тестування, які мають функціональність в Інтернеті


23

При блоці тестування функцій класу, який має приватні функції, які вимагають функціонування в Інтернеті. Як можна було б протестувати?

Наприклад:

public class Foo
{
    public int methodA()
    {
         int val = goOnlineToGetVal();

         return val;
    }

    private int goOnlineToGetVal()
    {
        CloudService c = new CloudService();
        int oval = c.getValueFromService();
        return oval;
    }
}

Якби я тестував функцію: 'methodA ()', він би спробував використати 'goOnlineToGetVal ()', який, у свою чергу, спробував би вийти в Інтернет, однак, якби цей тест був виконаний без функціональності. Як би я мав приблизно 100% покриття класу, не відвідуючи Інтернет?


Ваш метод просто називає хмарний api, чи робить це додатковою роботою?
Вінстон Еверт


4
Ін'єкційна залежність?
PhaDaPhunk

Відповіді:


76

new CloudService()

І там є ваша проблема.

Сучасна конструкція ОО рекомендує передавати такі залежності, а не будувати їх безпосередньо. Це може бути передано у саму функцію або в клас під час побудови. Він також може бути схоплений або об'єднаний контейнером Інверсії управління, якщо така складність є гарантованою.

З цього моменту стає досить тривіально переходити в макетну / фальшиву службу, щоб надати вам "онлайн" дані під час тестування. Що ще краще, це дозволяє вашому програмному забезпеченню бути досить гнучким, щоб ви могли швидко адаптуватися, якщо якийсь (урядовий?) Клієнт прийде разом і не хоче використовувати хмару для своїх цінностей. Або ви хочете скинути одного постачальника хмар для іншого. Або ...


7
Я думаю, що я просто наблизився до розуміння того, що таке чортове введення в залежність.
marczellm

Де найкраще створити всі екземпляри, потрібні моїй програмі? Як можна ближче до верхньої частини моєї заявки? Поки можна застосовувати лише ін'єкцію залежності; в якийсь момент вам потрібно буде створити екземпляри самостійно, а не передавати їх як аргументи.
Пол

3
@Paul - Це залежить. На мій досвід, програми дуже часто виглядають як двійкові дерева - один клас / функція / модуль склеює два разом, щоб забезпечити більш складну поведінку. Один із таких класів "клею" - це той, який конкретизує конкретну реалізацію, яка, в свою чергу, використовується чимось вище, що склеює його чимось іншим, а це, в свою чергу ..., поки ви нарешті не дістанетесь до точки входу, яка склеїть великі шматки разом узгоджено "Найкраще" місце - це місце, яке дозволяє вашому коду робити те, що йому потрібно робити, не примушуючи його робити чи знати про речі, які він не повинен. Він буде різним.
Теластин

2
@Paul Зазвичай ваша програма ділиться між "бібліотекою", яка безпосередньо перевіряється і має використовувати цей вид введення залежності, та кодом, що залежить від програми. Останній зазвичай зводиться до деякого графічного інтерфейсу, деякої веб-служби або до якогось інтерфейсу командного рядка, який безпосередньо викликає бібліотеку із наданими користувачем даними. По суті, специфічний для програми код створить конкретні реалізації, яких очікує залежна бібліотека.
Darkhogg

@Paul Погляньте на контейнери IoC, такі як Castle Windsor, StructureMap, Ninject та Unity. Вони аж ніяк не єдиний спосіб зробити ін'єкцію залежності, але вони можуть бути дуже інформативними з точки зору роздумів про побудову об'єктного графіка, зверху вниз
Бен Ааронсон,

37

Я би реалізував це так:

public class Foo
{
    private ICloudService cloudService;

    public Foo(ICloudService s)
    {
       cloudService=s;
    }

    public int methodA()
    {
         int val = goOnlineToGetVal();

         return val;
    }

    private int goOnlineToGetVal()
    {
        int oval = cloudService.getValueFromService();
        return oval;
    }
}

Інтерфейс ICloudServiceможе бути реалізований з макетом для тестування, або з "справжньою" хмарною службою. Коли інстанція new CloudService()є обов'язковою для кожного дзвінка getValueFromServiceабо CloudServiceє від сторонніх API, які неможливо змінити, реалізуйте обгортку, виходячи з ICloudServiceта виконуючи відповідні виклики.


1
Це, безумовно, шлях. Є бібліотеки класів, які можуть знущатися над інтерфейсом, даючи вам абсолютний контроль над тестом.
Грег Бургхардт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.